Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Sylvie Barlow <sylvie.c.barlow@gmail.com> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
- Loading branch information
1 parent
7ed1dc9
commit c239f0b
Showing
2 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* | ||
* Copyright (C) 2018 Sylvie Barlow <sylvie.c.barlow@gmail.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 any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
* 02110-1301, USA. | ||
* | ||
* You can also choose to distribute this program under the terms of | ||
* the Unmodified Binary Distribution Licence (as given in the file | ||
* COPYING.UBDL), provided that you have satisfied its requirements. | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||
|
||
#include <stdint.h> | ||
#include <unistd.h> | ||
#include <ipxe/bitbash.h> | ||
#include <ipxe/mii_bit.h> | ||
|
||
/** | ||
* Transfer bits over MII bit-bashing interface | ||
* | ||
* @v basher Bit basher | ||
* @v mask Mask | ||
* @v write Data to write | ||
* @ret read Data read | ||
*/ | ||
static uint32_t mii_bit_xfer ( struct bit_basher *basher, | ||
uint32_t mask, uint32_t write ) { | ||
uint32_t read = 0; | ||
int bit; | ||
|
||
for ( ; mask ; mask >>= 1 ) { | ||
|
||
/* Delay */ | ||
udelay ( 1 ); | ||
|
||
/* Write bit to basher */ | ||
write_bit ( basher, MII_BIT_MDIO, ( write & mask ) ); | ||
|
||
/* Read bit from basher */ | ||
bit = read_bit ( basher, MII_BIT_MDIO ); | ||
read <<= 1; | ||
read |= ( bit & 1 ); | ||
|
||
/* Set clock high */ | ||
write_bit ( basher, MII_BIT_MDC, 1 ); | ||
|
||
/* Delay */ | ||
udelay ( 1 ); | ||
|
||
/* Set clock low */ | ||
write_bit ( basher, MII_BIT_MDC, 0 ); | ||
} | ||
return read; | ||
} | ||
|
||
/** | ||
* Read or write via MII bit-bashing interface | ||
* | ||
* @v basher Bit basher | ||
* @v phy PHY address | ||
* @v reg Register address | ||
* @v data Data to write | ||
* @v cmd Command | ||
* @ret data Data read | ||
*/ | ||
static unsigned int mii_bit_rw ( struct bit_basher *basher, | ||
unsigned int phy, unsigned int reg, | ||
unsigned int data, unsigned int cmd ) { | ||
|
||
/* Initiate drive for write */ | ||
write_bit ( basher, MII_BIT_DRIVE, 1 ); | ||
|
||
/* Write start */ | ||
mii_bit_xfer ( basher, MII_BIT_START_MASK, MII_BIT_START ); | ||
|
||
/* Write command */ | ||
mii_bit_xfer ( basher, MII_BIT_CMD_MASK, cmd ); | ||
|
||
/* Write PHY address */ | ||
mii_bit_xfer ( basher, MII_BIT_PHY_MASK, phy ); | ||
|
||
/* Write register address */ | ||
mii_bit_xfer ( basher, MII_BIT_REG_MASK, reg ); | ||
|
||
/* Switch drive to read if applicable */ | ||
write_bit ( basher, MII_BIT_DRIVE, ( cmd & MII_BIT_CMD_RW ) ); | ||
|
||
/* Allow space for turnaround */ | ||
mii_bit_xfer ( basher, MII_BIT_SWITCH_MASK, MII_BIT_SWITCH ); | ||
|
||
/* Read or write data */ | ||
data = mii_bit_xfer (basher, MII_BIT_DATA_MASK, data ); | ||
|
||
/* Initiate drive for read */ | ||
write_bit ( basher, MII_BIT_DRIVE, 0 ); | ||
|
||
return data; | ||
} | ||
|
||
/** | ||
* Read from MII register | ||
* | ||
* @v mdio MII interface | ||
* @v phy PHY address | ||
* @v reg Register address | ||
* @ret data Data read, or negative error | ||
*/ | ||
static int mii_bit_read ( struct mii_interface *mdio, unsigned int phy, | ||
unsigned int reg ) { | ||
struct mii_bit_basher *miibit = | ||
container_of ( mdio, struct mii_bit_basher, mdio ); | ||
struct bit_basher *basher = &miibit->basher; | ||
|
||
return mii_bit_rw ( basher, phy, reg, 0, MII_BIT_CMD_READ ); | ||
} | ||
|
||
/** | ||
* Write to MII register | ||
* | ||
* @v mdio MII interface | ||
* @v phy PHY address | ||
* @v reg Register address | ||
* @v data Data to write | ||
* @ret rc Return status code | ||
*/ | ||
static int mii_bit_write ( struct mii_interface *mdio, unsigned int phy, | ||
unsigned int reg, unsigned int data ) { | ||
struct mii_bit_basher *miibit = | ||
container_of ( mdio, struct mii_bit_basher, mdio ); | ||
struct bit_basher *basher = &miibit->basher; | ||
|
||
mii_bit_rw ( basher, phy, reg, data, MII_BIT_CMD_WRITE ); | ||
return 0; | ||
} | ||
|
||
/** MII bit basher operations */ | ||
static struct mii_operations mii_bit_op = { | ||
.read = mii_bit_read, | ||
.write = mii_bit_write, | ||
}; | ||
|
||
/** | ||
* Initialise bit-bashing interface | ||
* | ||
* @v miibit MII bit basher | ||
*/ | ||
void init_mii_bit_basher ( struct mii_bit_basher *miibit ) { | ||
mdio_init ( &miibit->mdio, &mii_bit_op ); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#ifndef _IPXE_MII_BIT_H | ||
#define _IPXE_MII_BIT_H | ||
|
||
/** @file | ||
* | ||
* MII bit-bashing interface | ||
* | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||
|
||
#include <ipxe/mii.h> | ||
#include <ipxe/bitbash.h> | ||
|
||
#define MII_BIT_START 0xffffffff /**< Start */ | ||
#define MII_BIT_START_MASK 0x80000000 /**< Start mask */ | ||
|
||
#define MII_BIT_CMD_MASK 0x00000008 /**< Command mask */ | ||
#define MII_BIT_CMD_READ 0x00000006 /**< Command read */ | ||
#define MII_BIT_CMD_WRITE 0x00000005 /**< Command write */ | ||
#define MII_BIT_CMD_RW 0x00000001 /**< Command read or write */ | ||
|
||
#define MII_BIT_PHY_MASK 0x00000010 /**< PHY mask */ | ||
|
||
#define MII_BIT_REG_MASK 0x00000010 /**< Register mask */ | ||
|
||
#define MII_BIT_SWITCH 0x00000002 /**< Switch */ | ||
#define MII_BIT_SWITCH_MASK 0x00000002 /**< Switch mask */ | ||
|
||
#define MII_BIT_DATA_MASK 0x00008000 /**< Data mask */ | ||
|
||
/** A bit-bashing MII interface */ | ||
struct mii_bit_basher { | ||
/** MII interface */ | ||
struct mii_interface mdio; | ||
/** Bit-bashing interface */ | ||
struct bit_basher basher; | ||
}; | ||
|
||
/** Bit indices used for MII bit-bashing interface */ | ||
enum { | ||
/** MII clock */ | ||
MII_BIT_MDC = 0, | ||
/** MII data */ | ||
MII_BIT_MDIO, | ||
/** MII data direction */ | ||
MII_BIT_DRIVE, | ||
}; | ||
|
||
/** Delay between MDC transitions */ | ||
#define MII_BIT_UDELAY 1 | ||
|
||
extern void init_mii_bit_basher ( struct mii_bit_basher *miibit ); | ||
|
||
#endif /* _IPXE_MII_BIT_H */ |