Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[pandora-kernel.git] / include / linux / mii.h
index 151b7e0..359fba8 100644 (file)
 #define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
 #define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
 
+/* Flow control flags */
+#define FLOW_CTRL_TX           0x01
+#define FLOW_CTRL_RX           0x02
+
 /* This structure is used in all SIOCxMIIxxx ioctl calls */
 struct mii_ioctl_data {
        __u16           phy_id;
@@ -235,5 +239,44 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
        return 0;
 }
 
+/**
+ * mii_advertise_flowctrl - get flow control advertisement flags
+ * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
+ */
+static inline u16 mii_advertise_flowctrl(int cap)
+{
+       u16 adv = 0;
+
+       if (cap & FLOW_CTRL_RX)
+               adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+       if (cap & FLOW_CTRL_TX)
+               adv ^= ADVERTISE_PAUSE_ASYM;
+
+       return adv;
+}
+
+/**
+ * mii_resolve_flowctrl_fdx
+ * @lcladv: value of MII ADVERTISE register
+ * @rmtadv: value of MII LPA register
+ *
+ * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
+ */
+static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
+{
+       u8 cap = 0;
+
+       if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
+               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
+       } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
+               if (lcladv & ADVERTISE_PAUSE_CAP)
+                       cap = FLOW_CTRL_RX;
+               else if (rmtadv & ADVERTISE_PAUSE_CAP)
+                       cap = FLOW_CTRL_TX;
+       }
+
+       return cap;
+}
+
 #endif /* __KERNEL__ */
 #endif /* __LINUX_MII_H__ */