2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * Manage the atheros ethernet PHY.
26 * All definitions in this file are operating system independent!
30 #include <linux/types.h>
34 #include <asm/addrspace.h>
36 #include "athr_s27_phy.h"
39 //#include "phy.h" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
40 #define ath_gmac_unit2name(_unit) (_unit ? "eth1" : "eth0")
42 extern int ath_gmac_miiphy_read(char *devname, uint32_t phaddr, uint8_t reg, uint16_t *data);
43 extern int ath_gmac_miiphy_write(char *devname, uint32_t phaddr, uint8_t reg, uint16_t data);
45 void athrs27_reg_rmw(unsigned int s27_addr, unsigned int s27_write_data);
47 #define phy_reg_read(base, addr, reg) \
48 ath_gmac_miiphy_read(ath_gmac_unit2name(base), addr, reg, NULL)
50 #define phy_reg_write(base, addr, reg, data) \
51 ath_gmac_miiphy_write(ath_gmac_unit2name(base), addr, reg, data)
61 /* PHY selections and access functions */
74 #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
75 #define DRV_MSG(x,a,b,c,d,e,f)
76 #define DRV_PRINT(DBG_SW,X)
78 #define ATHR_LAN_PORT_VLAN 1
79 #define ATHR_WAN_PORT_VLAN 2
80 #define ENET_UNIT_LAN 1
81 #define ENET_UNIT_WAN 0
86 #define ATHR_PHY0_ADDR 0x0
87 #define ATHR_PHY1_ADDR 0x1
88 #define ATHR_PHY2_ADDR 0x2
89 #define ATHR_PHY3_ADDR 0x3
90 #define ATHR_PHY4_ADDR 0x4
92 #define MODULE_NAME "ATHRS27"
95 * Track per-PHY port information.
100 BOOL isEnetPort; /* normal enet port */
101 BOOL isPhyAlive; /* last known state of link */
102 int ethUnit; /* MAC associated with this phy port */
104 uint32_t phyAddr; /* PHY registers associated with this phy port */
105 uint32_t VLANTableSetting; /* Value to be written to VLAN table */
109 * Per-PHY information, indexed by PHY unit number.
111 static athrPhyInfo_t athrPhyInfo[] = {
113 {TRUE, /* port 1 -- LAN port 1 */
121 {TRUE, /* port 2 -- LAN port 2 */
129 {TRUE, /* port 3 -- LAN port 3 */
138 {TRUE, /* port 4 -- LAN port 4 */
143 ATHR_LAN_PORT_VLAN /* Send to all ports */
146 {TRUE, /* port 5 -- WAN Port 5 */
151 ATHR_LAN_PORT_VLAN /* Send to all ports */
154 {FALSE, /* port 0 -- cpu port 0 */
165 #define ATHR_GLOBALREGBASE 0
167 #define ATHR_PHY_MAX 5
169 /* Range of valid PHY IDs is [MIN..MAX] */
170 #define ATHR_ID_MIN 0
171 #define ATHR_ID_MAX (ATHR_PHY_MAX-1)
174 /* Convenience macros to access myPhyInfo */
175 #define ATHR_IS_ENET_PORT(phyUnit) (athrPhyInfo[phyUnit].isEnetPort)
176 #define ATHR_IS_PHY_ALIVE(phyUnit) (athrPhyInfo[phyUnit].isPhyAlive)
177 #define ATHR_ETHUNIT(phyUnit) (athrPhyInfo[phyUnit].ethUnit)
178 #define ATHR_PHYBASE(phyUnit) (athrPhyInfo[phyUnit].phyBase)
179 #define ATHR_PHYADDR(phyUnit) (athrPhyInfo[phyUnit].phyAddr)
180 #define ATHR_VLAN_TABLE_SETTING(phyUnit) (athrPhyInfo[phyUnit].VLANTableSetting)
183 #define ATHR_IS_ETHUNIT(phyUnit, ethUnit) \
184 (ATHR_IS_ENET_PORT(phyUnit) && \
185 ATHR_ETHUNIT(phyUnit) == (ethUnit))
187 #define ATHR_IS_WAN_PORT(phyUnit) (!(ATHR_ETHUNIT(phyUnit)==ENET_UNIT_LAN))
189 /* Forward references */
190 BOOL athrs27_phy_is_link_alive(int phyUnit);
191 uint32_t athrs27_reg_read(uint32_t reg_addr);
192 void athrs27_reg_write(uint32_t reg_addr, uint32_t reg_val);
193 unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr);
194 void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data);
197 void athrs27_powersave_off(int phy_addr)
199 s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0x29);
200 s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x36c0);
203 void athrs27_sleep_off(int phy_addr)
205 s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0xb);
206 s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x3c00);
209 void athrs27_force_100M(int phyAddr,int duplex)
212 * Force MDI and MDX to alternate ports
213 * Phy 0,2 and 4 -- MDI
218 s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
221 s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
224 s27_wr_phy(phyAddr,0x1d,0x29);
225 s27_wr_phy(phyAddr,0x1e,0x0);
226 s27_wr_phy(phyAddr,0x10,0xc60);
227 s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0xa000|(duplex << 8)));
230 void athrs27_force_10M(int phyAddr,int duplex)
233 athrs27_powersave_off(phyAddr);
234 athrs27_sleep_off(phyAddr);
236 s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0x8000 |(duplex << 8)));
239 int athrs27_reg_init(void)
245 /* if using header for register configuration, we have to */
246 /* configure s27 register after frame transmission is enabled */
247 athrs27_reg_rmw(0x8,(1<<28)); /* Set WAN port is connected to GE0 */
249 #if defined(S27_FORCE_100M)
250 athrs27_force_100M(ATHR_PHY4_ADDR,1);
251 #elif defined(S27_FORCE_10M)
252 athrs27_force_10M(ATHR_PHY4_ADDR,1);
254 s27_wr_phy(ATHR_PHY4_ADDR,ATHR_PHY_CONTROL,0x9000);
258 printf(MODULE_NAME":OPERATIONAL_MODE_REG0:%x\n",athrs27_reg_read(OPERATIONAL_MODE_REG0));
259 printf(MODULE_NAME":REG 0x4-->:%x\n",athrs27_reg_read(0x4));
260 printf(MODULE_NAME":REG 0x2c-->:%x\n",athrs27_reg_read(0x2c));
261 printf(MODULE_NAME":REG 0x8-->:%x\n",athrs27_reg_read(0x8));
267 int athrs27_reg_init_lan(void)
274 uint32_t phyAddr = 0;
278 //printf(MODULE_NAME ": resetting s27\n");
279 athrs27_reg_write(0x0, athrs27_reg_read(0x0)|0x80000000);
283 if(!(athrs27_reg_read(0x0)&0x80000000))
286 //printf(MODULE_NAME ": s27 reset done\n");
287 athrs27_reg_write(PORT_STATUS_REGISTER0,0x4e);
289 athrs27_reg_rmw(OPERATIONAL_MODE_REG0,(1<<6)); /* Set GMII mode */
291 if (is_emu() || is_wasp()) {
292 athrs27_reg_rmw(0x2c,((1<<26)| (1<<16) | 0x1)); /* FiX ME: EBU debug */
295 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
297 phyAddr = ATHR_PHYADDR(phyUnit);
299 #if defined(S27_FORCE_100M)
300 athrs27_force_100M(phyAddr,1);
301 #elif defined(S27_FORCE_10M)
302 athrs27_force_10M(phyAddr,1);
304 s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,0x9000);
308 rd_val = s27_rd_phy(phyAddr,ATHR_PHY_FUNC_CONTROL);
309 printf("S27 ATHR_PHY_FUNC_CONTROL (%d):%x\n",phyAddr,rd_val);
310 rd_val = s27_rd_phy(phyAddr,ATHR_PHY_ID1);
311 printf("S27 PHY ID (%d) :%x\n",phyAddr, rd_val);
312 rd_val = s27_rd_phy(phyAddr,ATHR_PHY_SPEC_STATUS);
313 printf("S27 PHY CTRL (%d) :%x\n",phyAddr, rd_val);
314 rd_val = s27_rd_phy(phyAddr,ATHR_PHY_STATUS);
315 printf("S27 ATHR PHY STATUS (%d) :%x\n",phyAddr, rd_val);
320 * status[1:0]=2'h2; - (0x10 - 1000 Mbps , 0x01 - 100Mbps, 0x0 - 10 Mbps)
321 * status[2]=1'h1; - Tx Mac En
322 * status[3]=1'h1; - Rx Mac En
323 * status[4]=1'h1; - Tx Flow Ctrl En
324 * status[5]=1'h1; - Rx Flow Ctrl En
325 * status[6]=1'h1; - Duplex Mode
327 athrs27_reg_write(PORT_STATUS_REGISTER1, 0x200); /* LAN - 1 */
328 athrs27_reg_write(PORT_STATUS_REGISTER2, 0x200); /* LAN - 2 */
329 athrs27_reg_write(PORT_STATUS_REGISTER3, 0x200); /* LAN - 3 */
330 athrs27_reg_write(PORT_STATUS_REGISTER4, 0x200); /* LAN - 4 */
333 athrs27_reg_write(PORT_STATUS_REGISTER1, 0x4C); /* LAN - 1 */
334 athrs27_reg_write(PORT_STATUS_REGISTER2, 0x4c); /* LAN - 2 */
335 athrs27_reg_write(PORT_STATUS_REGISTER3, 0x4c); /* LAN - 3 */
336 athrs27_reg_write(PORT_STATUS_REGISTER4, 0x4c); /* LAN - 4 */
340 athrs27_reg_write(0x38, 0xc000050e);
343 * status[11]=1'h0; - CPU Disable
344 * status[7] = 1'b1; - Learn One Lock
345 * status[14] = 1'b0; - Learn Enable
347 #ifdef ATHEROS_HEADER_EN
348 athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4804);
350 /* Atheros Header Disable */
351 athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4004);
354 /* Tag Priority Mapping */
355 athrs27_reg_write(0x70, 0xfa50);
357 /* Enable ARP packets to CPU port */
358 athrs27_reg_write(S27_ARL_TBL_CTRL_REG,(athrs27_reg_read(S27_ARL_TBL_CTRL_REG) | 0x100000));
360 /* Enable Broadcast packets to CPU port */
361 athrs27_reg_write(S27_FLD_MASK_REG,(athrs27_reg_read(S27_FLD_MASK_REG) |
362 S27_ENABLE_CPU_BROADCAST | S27_ENABLE_CPU_BCAST_FWD ));
367 /******************************************************************************
369 * athrs27_phy_is_link_alive - test to see if the specified link is alive
372 * TRUE --> link is alive
373 * FALSE --> link is down
376 athrs27_phy_is_link_alive(int phyUnit)
378 uint16_t phyHwStatus;
381 phyAddr = ATHR_PHYADDR(phyUnit);
382 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_SPEC_STATUS);
384 if (phyHwStatus & ATHR_STATUS_LINK_PASS)
390 /******************************************************************************
392 * athrs27_phy_setup - reset and setup the PHY associated with
393 * the specified MAC unit number.
395 * Resets the associated PHY port.
398 * TRUE --> associated PHY is alive
399 * FALSE --> no LINKs on this ethernet unit
402 athrs27_phy_setup(int ethUnit)
405 uint16_t phyHwStatus;
408 BOOL foundPhy = FALSE;
409 uint32_t phyAddr = 0;
411 /* See if there's any configuration data for this enet */
412 /* start auto negogiation on each phy */
413 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
416 phyAddr = ATHR_PHYADDR(phyUnit);
418 if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
422 s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);
424 s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
425 | ATHR_CTRL_SOFTWARE_RESET);
428 //printf("############ is emulation ############\n");
430 if(ATHR_ETHUNIT(phyUnit) == ENET_UNIT_WAN) {
431 s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);
432 s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
433 s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
434 s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
435 | ATHR_CTRL_SOFTWARE_RESET);
439 s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,(ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE |
440 ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL));
441 s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
442 s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
443 s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
444 | ATHR_CTRL_SOFTWARE_RESET);
449 return FALSE; /* No PHY's configured for this ethUnit */
453 * After the phy is reset, it takes a little while before
454 * it can respond properly.
457 if (ethUnit == ENET_UNIT_LAN)
464 * Wait up to 3 seconds for ALL associated PHYs to finish
465 * autonegotiation. The only way we get out of here sooner is
466 * if ALL PHYs are connected AND finish autonegotiation.
468 for (phyUnit=0; (phyUnit < ATHR_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
469 if (ATHR_ETHUNIT(phyUnit) == ENET_UNIT_WAN)
474 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
476 if (ATHR_RESET_DONE(phyHwStatus)) {
477 DRV_PRINT(DRV_DEBUG_PHYSETUP,
478 ("Port %d, Neg Success\n", phyUnit));
482 DRV_PRINT(DRV_DEBUG_PHYSETUP,
483 ("Port %d, Negogiation timeout\n", phyUnit));
486 if (--timeout == 0) {
487 DRV_PRINT(DRV_DEBUG_PHYSETUP,
488 ("Port %d, Negogiation timeout\n", phyUnit));
494 /* extend the cable length */
495 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x14);
496 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xf52);
498 /* Force Class A setting phys */
499 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 4);
500 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xebbb);
501 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 5);
502 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0x2c47);
505 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x3c);
506 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0x1c1);
507 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x37);
508 s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xd600);
512 /* turn off power saving */
513 s27_wr_phy(phyUnit, 29, 41);
514 s27_wr_phy(phyUnit, 30, 0);
515 //printf("def_ S27_VER_1_0\n");
520 * All PHYs have had adequate time to autonegotiate.
521 * Now initialize software status.
523 * It's possible that some ports may take a bit longer
524 * to autonegotiate; but we can't wait forever. They'll
525 * get noticed by mv_phyCheckStatusChange during regular
526 * polling activities.
528 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
529 if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
533 if (athrs27_phy_is_link_alive(phyUnit)) {
535 ATHR_IS_PHY_ALIVE(phyUnit) = TRUE;
537 ATHR_IS_PHY_ALIVE(phyUnit) = FALSE;
539 DRV_PRINT(DRV_DEBUG_PHYSETUP,
540 ("eth%d: Phy Specific Status=%4.4x\n",
542 s27_rd_phy(ATHR_PHYADDR(phyUnit),ATHR_PHY_SPEC_STATUS)));
545 return (liveLinks > 0);
548 /******************************************************************************
550 * athrs27_phy_is_fdx - Determines whether the phy ports associated with the
551 * specified device are FULL or HALF duplex.
558 athrs27_phy_is_fdx(int ethUnit,int phyUnit)
561 uint16_t phyHwStatus;
564 if (ethUnit == ENET_UNIT_LAN)
567 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
568 if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
572 if (athrs27_phy_is_link_alive(phyUnit)) {
574 phyAddr = ATHR_PHYADDR(phyUnit);
577 phyHwStatus = s27_rd_phy (phyAddr, ATHR_PHY_SPEC_STATUS);
578 if(phyHwStatus & ATHR_STATUS_RESOVLED)
582 if (phyHwStatus & ATHER_STATUS_FULL_DUPLEX) {
590 /******************************************************************************
592 * athrs27_phy_speed - Determines the speed of phy ports associated with the
596 * ATHR_PHY_SPEED_10T, AG7240_PHY_SPEED_100T;
597 * ATHR_PHY_SPEED_1000T;
601 athrs27_phy_speed(int ethUnit,int phyUnit)
603 uint16_t phyHwStatus;
606 int phySpeed = _100BASET;
607 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
608 if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
612 phyAddr = ATHR_PHYADDR(phyUnit);
615 if (athrs27_phy_is_link_alive(phyUnit)) {
618 phyHwStatus = s27_rd_phy(phyAddr,
619 ATHR_PHY_SPEC_STATUS);
620 if(phyHwStatus & ATHR_STATUS_RESOVLED)
625 phyHwStatus = ((phyHwStatus & ATHER_STATUS_LINK_MASK) >>
626 ATHER_STATUS_LINK_SHIFT);
628 switch(phyHwStatus) {
633 phySpeed = _100BASET;
636 phySpeed = _1000BASET;
639 printf("Unkown speed read!\n");
643 phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_ADDRESS, 0x18);
645 if(phySpeed == _100BASET) {
646 phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0xba8);
648 phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0x2ea);
652 if (ethUnit == ENET_UNIT_LAN)
653 phySpeed = _1000BASET;
658 /*****************************************************************************
660 * athr_phy_is_up -- checks for significant changes in PHY state.
662 * A "significant change" is:
663 * dropped link (e.g. ethernet cable unplugged) OR
664 * autonegotiation completed + link (e.g. ethernet cable plugged in)
666 * When a PHY is plugged in, phyLinkGained is called.
667 * When a PHY is unplugged, phyLinkLost is called.
671 athrs27_phy_is_up(int ethUnit)
674 uint16_t phyHwStatus, phyHwControl;
675 athrPhyInfo_t *lastStatus;
682 for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
683 if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
687 phyAddr = ATHR_PHYADDR(phyUnit);
689 lastStatus = &athrPhyInfo[phyUnit];
690 if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
691 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_SPEC_STATUS);
693 /* See if we've lost link */
694 if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
698 DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",
700 printf("enet%d port%d down\n",ethUnit, phyUnit);
701 lastStatus->isPhyAlive = FALSE;
703 } else { /* last known link status was DEAD */
704 /* Check for reset complete */
707 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);
709 s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
712 s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
715 if((phyHwStatus & 0x4)==0)
717 s27_wr_phy(phyAddr,0x9,0x0);
719 s27_wr_phy(phyAddr,0x4,0x41);
720 s27_wr_phy(phyAddr,0x0,0x9000);
724 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
725 if (!ATHR_RESET_DONE(phyHwStatus))
728 phyHwControl = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
729 phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);
731 /* Check for AutoNegotiation complete */
732 if ((!(phyHwControl & ATHR_CTRL_AUTONEGOTIATION_ENABLE))
733 || ATHR_AUTONEG_DONE(phyHwStatus)) {
734 phyHwStatus = s27_rd_phy(phyAddr,
735 ATHR_PHY_SPEC_STATUS);
737 if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
740 printf("enet%d port%d up\n",ethUnit, phyUnit);
741 DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",
743 lastStatus->isPhyAlive = TRUE;
751 unsigned int athrs27_reg_read(unsigned int s27_addr)
753 unsigned int addr_temp;
754 unsigned int s27_rd_csr_low, s27_rd_csr_high, s27_rd_csr;
755 unsigned int data,unit = 0;
756 unsigned int phy_address, reg_address;
758 addr_temp = s27_addr >>2;
759 data = addr_temp >> 7;
767 else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
771 phy_reg_write(unit,phy_address, reg_address, data);
773 phy_address = (0x17 & ((addr_temp >> 4) | 0x10));
774 reg_address = ((addr_temp << 1) & 0x1e);
775 s27_rd_csr_low = (uint32_t) phy_reg_read(unit,phy_address, reg_address);
777 reg_address = reg_address | 0x1;
778 s27_rd_csr_high = (uint32_t) phy_reg_read(unit,phy_address, reg_address);
779 s27_rd_csr = (s27_rd_csr_high << 16) | s27_rd_csr_low ;
784 void athrs27_reg_write(unsigned int s27_addr, unsigned int s27_write_data)
786 unsigned int addr_temp;
788 unsigned int phy_address, reg_address,unit = 0;
790 addr_temp = (s27_addr ) >>2;
791 data = addr_temp >> 7;
799 else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
802 phy_reg_write(unit,phy_address, reg_address, data);
804 phy_address = (0x17 & ((addr_temp >> 4) | 0x10));
806 reg_address = (((addr_temp << 1) & 0x1e) | 0x1);
807 data = (s27_write_data >> 16) & 0xffff;
808 phy_reg_write(unit,phy_address, reg_address, data);
810 reg_address = ((addr_temp << 1) & 0x1e);
811 data = s27_write_data & 0xffff;
812 phy_reg_write(unit,phy_address, reg_address, data);
816 void athrs27_reg_rmw(unsigned int s27_addr, unsigned int s27_write_data)
818 int val = athrs27_reg_read(s27_addr);
819 athrs27_reg_write(s27_addr,(val | s27_write_data));
822 unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr)
828 } else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
831 val = (uint32_t) phy_reg_read(unit, phy_addr, reg_addr);
835 void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data)
841 } else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
845 phy_reg_write(unit, phy_addr, reg_addr, write_data);
847 int athrs27_mdc_check(void)
851 for (i=0; i<4000; i++) {
852 if(athrs27_reg_read(0x10c) != 0x18007fff)