diff --git a/userspace/wrsw_hal/driver_stuff.h b/userspace/wrsw_hal/driver_stuff.h
index b1c1a4d173a61373935405a9357015e9233e9d9a..0715bf0d4b059089ad567a14b39ad6cef8eadd66 100644
--- a/userspace/wrsw_hal/driver_stuff.h
+++ b/userspace/wrsw_hal/driver_stuff.h
@@ -1,8 +1,10 @@
+#include <regs/lpdc_mdio_regs.h>
 
 #define PRIV_IOCGCALIBRATE (SIOCDEVPRIVATE + 1)
 #define PRIV_IOCGGETPHASE (SIOCDEVPRIVATE + 2)
 #define PRIV_IOCREADREG (SIOCDEVPRIVATE + 3)
 #define PRIV_IOCPHYREG (SIOCDEVPRIVATE + 4)
+#define PRIV_IOCLPDCREG (SIOCDEVPRIVATE + 5)
 
 #define NIC_READ_PHY_CMD(addr)  (((addr) & 0xff) << 16)
 #define NIC_RESULT_DATA(val) ((val) & 0xffff)
@@ -10,32 +12,9 @@
  | (1 << 31) \
  | ((value) & 0xffff))
 
-/*
- * MDIO registers used in Low Phase Drift Calibration
- * See kernel/wbgen-regs/endpoint-mdio.h
- */
-
-// address of status and control registers
-#define MDIO_LPC_STAT 18
-#define MDIO_LPC_CTRL 19
-
-// flags for status and control registers
-#define MDIO_LPC_STAT_RESET_TX_DONE (1 << 0)
-#define MDIO_LPC_STAT_LINK_UP       (1 << 1)
-#define MDIO_LPC_STAT_LINK_ALIGNED  (1 << 2)
-#define MDIO_LPC_STAT_RESET_RX_DONE (1 << 3)
-
-#define MDIO_LPC_CTRL_RESET_TX      (1 << 0)
-#define MDIO_LPC_CTRL_TX_ENABLE     (1 << 1)
-#define MDIO_LPC_CTRL_RX_ENABLE     (1 << 2)
-#define MDIO_LPC_CTRL_RESET_RX      (1 << 3)
-
-#define MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK (1 << 14)
-#define MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK (0 << 14)
-#define MDIO_LPC_STAT_DBG_DATA      (1 << 4)
+#define LPDC_MDIO_CTRL_DMTD_SOURCE_TXOUTCLK (1 << LPDC_MDIO_CTRL_DMTD_CLK_SEL_SHIFT)
+#define LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK (0 << LPDC_MDIO_CTRL_DMTD_CLK_SEL_SHIFT)
 
-#define MDIO_LPC_CTRL_DBG_SHIFT_EN  (1 << 8)
-#define MDIO_LPC_CTRL_DBG_TRIG      (1 << 10)
 /*
  * Address and mask to discover support for Low Phase Drift
  * Calibration, taken from endpoint-regs.h
diff --git a/userspace/wrsw_hal/hal_port_fsm.c b/userspace/wrsw_hal/hal_port_fsm.c
index 651592c5e825fe463e2ecf9f7b0608dd9268aa40..26c809d10bd198c416c88167d9bc61e1a7ab4615 100644
--- a/userspace/wrsw_hal/hal_port_fsm.c
+++ b/userspace/wrsw_hal/hal_port_fsm.c
@@ -158,9 +158,11 @@ static int port_fsm_state_disabled(fsm_t *fsm, int eventMsk, int isNewState) {
 
 		// make sure the PHY calibration circuitry is put in a KNOWN state
 		if( ps->lpdc.isSupported )	{
-			pcs_writel(ps,
-					MDIO_LPC_CTRL_RESET_RX | MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK
-							| MDIO_LPC_CTRL_TX_ENABLE, MDIO_LPC_CTRL);
+			lpdc_writel(ps,
+				    LPDC_MDIO_CTRL_RX_SW_RESET
+				    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK
+				    | LPDC_MDIO_CTRL_TX_ENABLE,
+				    LPDC_MDIO_CTRL);
 
 		}
 		// Disable tracker
@@ -209,14 +211,16 @@ static int port_fsm_state_link_down(fsm_t *fsm, int eventMsk, int isNewState) {
 		led_set_wrmode(ps->hw_index, SFP_LED_WRMODE_OFF);
 		led_set_synched(ps->hw_index, 0);
 
-		pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
-			      MDIO_LPC_CTRL_TX_ENABLE |
-			      MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-			      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_RX_SW_RESET
+			    | LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 		shw_udelay(1);
-		pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
-			      MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-			      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 	}
 
 	/* if final state reached for tx setup state machine then
@@ -350,10 +354,10 @@ static  int port_fsm_build_events(fsm_t *fsm) {
 	if ( ps->lpdc.isSupported ) {
 		uint32_t mioLpcStat;
 
-		if ( pcs_readl(ps, MDIO_LPC_STAT,&mioLpcStat) >= 0 ) {
-			if (mioLpcStat & MDIO_LPC_STAT_LINK_UP)
+		if (lpdc_readl(ps, LPDC_MDIO_STAT, &mioLpcStat) >= 0 ) {
+			if (mioLpcStat & LPDC_MDIO_STAT_LINK_UP)
 				portEventMask |= HAL_PORT_EVENT_EARLY_LINK_UP;
-			if (mioLpcStat & MDIO_LPC_STAT_LINK_ALIGNED)
+			if (mioLpcStat & LPDC_MDIO_STAT_LINK_ALIGNED)
 				portEventMask |= HAL_PORT_EVENT_RX_ALIGNED;
 		}
 	}
diff --git a/userspace/wrsw_hal/hal_port_fsm_rx.c b/userspace/wrsw_hal/hal_port_fsm_rx.c
index ddc2ab0ddcac19bbe85e38802d5215285e9e4088..4050be72b3aa6812b43ed4ff7c10cb9797850189 100644
--- a/userspace/wrsw_hal/hal_port_fsm_rx.c
+++ b/userspace/wrsw_hal/hal_port_fsm_rx.c
@@ -182,9 +182,10 @@ static int _hal_port_rx_setup_state_start(fsm_t *fsm, int eventMsk, int isNewSta
 			return 0;
 		}
 		// LPDC support
-		pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
-		MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-		MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 
 		if (_isHalRxSetupEventEarlyLinkUp(eventMsk)) {
 			halPortLpdcRx_t *rxSetup = ps->lpdc.rxSetup;
@@ -220,14 +221,16 @@ static int _hal_port_rx_setup_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNe
 	if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
 		halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
 
-		pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
-			      MDIO_LPC_CTRL_TX_ENABLE |
-			      MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-			      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_RX_SW_RESET
+			    | LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 		shw_udelay(1);
-		pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
-			      MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-			      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 
 		rxSetup->attempts++;
 		fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_WAIT_LOCK);
@@ -290,10 +293,11 @@ static int _hal_port_rx_setup_state_validate(fsm_t *fsm, int eventMsk, int isNew
 		int phase = _pll_state.channels[ps->hw_index].phase_loopback;
 		halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
 
-		pcs_writel(ps, MDIO_LPC_CTRL_RX_ENABLE |
-				MDIO_LPC_CTRL_TX_ENABLE |
-				MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-				MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_RX_ENABLE
+			    | LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+			    LPDC_MDIO_CTRL);
 		pcs_writel(ps, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR);
 
 		pr_info("wri%d: RX calibration complete at phase %d "
@@ -322,8 +326,10 @@ static int _hal_port_rx_setup_state_restart(fsm_t *fsm, int eventMsk, int isNewS
 	if ( isNewState ) {
 		// This timer is used to leave enough time to the FSM in the other side to detect a link down
 		libwr_tmo_restart(&ps->lpdc.rxSetup->restart_timeout);
-		pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE | MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
-		      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_TX_ENABLE
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_TXOUTCLK,
+			    LPDC_MDIO_CTRL);
 	} else {
 		if( libwr_tmo_expired( &ps->lpdc.rxSetup->restart_timeout ) ) {
 			fsm_fire_state(fsm,  HAL_PORT_RX_SETUP_STATE_INIT);
@@ -397,10 +403,10 @@ static  int port_rx_setup_fsm_build_events (fsm_t *fsm) {
 	if ( ps->lpdc.isSupported ) {
 		uint32_t mioLpcStat;
 
-		if ( pcs_readl(ps, MDIO_LPC_STAT,&mioLpcStat) >= 0 ) {
-			if (mioLpcStat & MDIO_LPC_STAT_LINK_UP)
+		if (lpdc_readl(ps, LPDC_MDIO_STAT,&mioLpcStat) >= 0 ) {
+			if (mioLpcStat & LPDC_MDIO_STAT_LINK_UP)
 				portEventMask |= HAL_PORT_RX_SETUP_EVENT_EARLY_LINK_UP;
-			if (mioLpcStat & MDIO_LPC_STAT_LINK_ALIGNED)
+			if (mioLpcStat & LPDC_MDIO_STAT_LINK_ALIGNED)
 				portEventMask |= HAL_PORT_RX_SETUP_EVENT_RX_ALIGNED;
 		}
 	}
diff --git a/userspace/wrsw_hal/hal_port_fsm_tx.c b/userspace/wrsw_hal/hal_port_fsm_tx.c
index bb766291ec8850b5f91929ee92340b580cdf353d..5bc5163030f3aecee9ddcbd2ac32cac814c45402 100644
--- a/userspace/wrsw_hal/hal_port_fsm_tx.c
+++ b/userspace/wrsw_hal/hal_port_fsm_tx.c
@@ -162,9 +162,10 @@ static int port_tx_setup_fsm_state_start(fsm_t *fsm, int eventMsk, int isNewStat
 		rts_enable_ptracker(ps->hw_index, 0);
 		rts_ptracker_set_average_samples(ps->hw_index, HAL_CAL_DMTD_SAMPLES);
 
-		pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
-			      MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
-			      MDIO_LPC_CTRL);
+		lpdc_writel(ps,
+			    LPDC_MDIO_CTRL_RX_SW_RESET
+			    | LPDC_MDIO_CTRL_DMTD_SOURCE_TXOUTCLK,
+			    LPDC_MDIO_CTRL);
 
 		/* start indicating LPDC rx calibration. */
 		led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_CALIB);
@@ -180,16 +181,18 @@ static int port_tx_setup_fsm_state_start(fsm_t *fsm, int eventMsk, int isNewStat
  */
 static int port_tx_setup_fsm_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNewState) {
 	struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
-
+	
 	rts_enable_ptracker(ps->hw_index, 0);
-	pcs_writel(ps, MDIO_LPC_CTRL_RESET_TX |
-		      MDIO_LPC_CTRL_RESET_RX |
-		      MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
-		      MDIO_LPC_CTRL);
+	lpdc_writel(ps,
+		    LPDC_MDIO_CTRL_TX_SW_RESET
+		    | LPDC_MDIO_CTRL_RX_SW_RESET
+		    | LPDC_MDIO_CTRL_DMTD_SOURCE_TXOUTCLK,
+		    LPDC_MDIO_CTRL);
 	shw_udelay(1);
-	pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
-		      MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
-		      MDIO_LPC_CTRL);
+	lpdc_writel(ps,
+		    LPDC_MDIO_CTRL_RX_SW_RESET
+		    | LPDC_MDIO_CTRL_DMTD_SOURCE_TXOUTCLK,
+		    LPDC_MDIO_CTRL);
 
 	fsm_fire_state(fsm,HAL_PORT_TX_SETUP_STATE_WAIT_LOCK);
 	return 0;
@@ -203,9 +206,8 @@ static int port_tx_setup_fsm_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNew
 static int port_tx_setup_fsm_state_wait_lock(fsm_t *fsm, int eventMsk, int isNewState) {
 	struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
 	uint32_t value;
-
-	if ( pcs_readl(ps, MDIO_LPC_STAT,&value)>=0 ) {
-		if ( (value & MDIO_LPC_STAT_RESET_TX_DONE)!=0 ) {
+	if (lpdc_readl(ps, LPDC_MDIO_STAT,&value) >= 0 ) {
+		if ( (value & LPDC_MDIO_STAT_TX_RST_DONE)!=0 ) {
 			ps->lpdc.txSetup->attempts++;
 
 			rts_enable_ptracker(ps->hw_index, 1);
@@ -307,10 +309,11 @@ static int port_tx_setup_fsm_state_validate(fsm_t *fsm, int eventMsk, int isNewS
 	rts_enable_ptracker(ps->hw_index, 0);
 
 	// enable the PCS on the port
-	pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
-		      MDIO_LPC_CTRL_TX_ENABLE |
-		      MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
-		      MDIO_LPC_CTRL);
+	lpdc_writel(ps,
+		    LPDC_MDIO_CTRL_RX_SW_RESET
+		    | LPDC_MDIO_CTRL_TX_ENABLE
+		    | LPDC_MDIO_CTRL_DMTD_SOURCE_RXRECCLK,
+		    LPDC_MDIO_CTRL);
 
 	led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_OFF);
 
diff --git a/userspace/wrsw_hal/hal_ports.c b/userspace/wrsw_hal/hal_ports.c
index 166a4f7b57441a1bfa05fbc78db8961659a26207..f7ea3a92fb40fdb1db9e1f733fa62b782fa74dff 100644
--- a/userspace/wrsw_hal/hal_ports.c
+++ b/userspace/wrsw_hal/hal_ports.c
@@ -295,6 +295,43 @@ int hal_port_shmem_init(char *logfilename)
 	return 0;
 }
 
+int lpdc_writel(struct hal_port_state *ps, uint16_t value, int reg)
+{
+	struct ifreq ifr;
+	uint32_t rv;
+
+	strncpy(ifr.ifr_name, ps->name, sizeof(ifr.ifr_name));
+
+	rv = NIC_WRITE_PHY_CMD(reg, value);
+	ifr.ifr_data = (void *)&rv;
+	if (ioctl(halPorts.hal_port_fd, PRIV_IOCLPDCREG, &ifr) < 0) {
+		pr_error("%s: ioctl failed writing at register adress %d\n",
+				__func__,reg);
+		return -1;
+	};
+
+	return 0;
+}
+
+int lpdc_readl(struct hal_port_state * p, int reg, uint32_t *value)
+{
+	struct ifreq ifr;
+
+	strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
+
+	*value = NIC_READ_PHY_CMD(reg);
+	ifr.ifr_data = (void *)value;
+	if (ioctl(halPorts.hal_port_fd, PRIV_IOCLPDCREG, &ifr) < 0) {
+		pr_error("%s: ioctl failed reading register at address %d\n",
+				__func__, reg);
+		return -1;
+	}
+
+	*value = NIC_RESULT_DATA(*value);
+	return 0;
+}
+
+
 int pcs_writel(struct hal_port_state *ps, uint16_t value, int reg)
 {
 	struct ifreq ifr;
diff --git a/userspace/wrsw_hal/hal_ports.h b/userspace/wrsw_hal/hal_ports.h
index e188f64245628c0d6c42364e3694560ac0e3796e..d964452de28b814e549948b8a2784ad7744a9736 100644
--- a/userspace/wrsw_hal/hal_ports.h
+++ b/userspace/wrsw_hal/hal_ports.h
@@ -68,6 +68,8 @@ extern int hal_check_running(void);
 extern int hal_add_cleanup_callback(hal_cleanup_callback_t cb);
 extern int pcs_writel(struct hal_port_state *p, uint16_t value, int reg);
 extern int pcs_readl(struct hal_port_state * p, int reg, uint32_t *value);
+extern int lpdc_writel(struct hal_port_state *p, uint16_t value, int reg);
+extern int lpdc_readl(struct hal_port_state * p, int reg, uint32_t *value);
 
 
 #endif