1/* 2 First pass at a common ethernet link-up message. Comments/bugs to guyton. 3 4 kextname: name of the driver or NULL if ok to use last word of the CFBundleIdentifier 5 netif: the network interface (used to get the bsd name) 6 megabits: 10, 100 or 1000 7 fullDuplex: true if full duplex, else half 8 flowState: results of negotiating flow control (who's sending pause) 9 port: string that matches the label printed next to the physcial port or null 10 loopback: loopback mode string or null 11 phyregs: six debug phy registers. 12 */ 13 14typedef enum { 15 kLinkUpFlow_None = 0, 16 kLinkUpFlow_PauseTxOnly = 1, 17 kLinkUpFlow_PauseRxOnly = 2, 18 kLinkUpFlow_Symmetric = 3, 19 /* as bits to construct above */ 20 kLinkFlow_Mask_TxPause= 0x1, 21 kLinkFlow_Mask_RxPause= 0x2 22} LinkUpFlow; 23 24enum { // recommended contents of phyregs, but driver & phy specific 25 kLinkUp_Phy_OurStatus = 0, 26 kLinkUp_Phy_ExtendedStatus, 27 kLinkUp_Phy_OurAdvertised, 28 kLinkUp_Phy_OurGigAdvertised, 29 kLinkUp_Phy_PeerAdvertised, 30 kLinkUp_Phy_PeerGigAdvertised, 31 32 LinkUp_Phy_Count // size of the array 33}; 34 35extern kmod_info_t KMOD_INFO_NAME; // generated by xcode for kexts 36 37static inline void LinkUpMessage( 38 char *buffer, // or null to only do the IOLog 39 int bufsize, // size of the buffer 40 const char *kextname, 41 IONetworkInterface *netif, 42 int megabits, 43 bool fullDuplex, 44 LinkUpFlow flowState, 45 const char *port, 46 UInt16 phyregs[LinkUp_Phy_Count], 47 const char *loopback 48) 49{ 50 char line[256]; 51 52 if (buffer == NULL || bufsize == 0) { 53 buffer = line; 54 bufsize = sizeof(line); 55 } 56 if (kextname && *kextname == 0) kextname = NULL; 57 if (port && *port == 0) port = NULL; 58 if (loopback && *loopback == 0) loopback = NULL; 59 60 // first find our kextname if null is passed in 61 if (kextname == NULL) { 62 char *period; 63 //kextname = rindex(KMOD_INFO_NAME.name, '.'); 64 kextname = KMOD_INFO_NAME.name; 65 while ((period = strchr(kextname, '.')) != NULL) { 66 kextname = ++period; 67 } 68 if (kextname == NULL || *kextname == 0) 69 kextname = "????"; 70 } 71 72 snprintf(buffer, bufsize, "Ethernet [%s]: Link up on %s%d, %d-%s, %s-duplex, %s flow-control%s%s, Debug [%04x,%04x,%04x,%04x,%04x,%04x]%s%s", 73 kextname, netif->getNamePrefix(), netif->getUnitNumber(), 74 (megabits > 999) ? (int)(megabits / 1000) : megabits, 75 (megabits > 999) ? "Gigabit" : "Megabit", 76 (fullDuplex) ? "Full" : "Half", 77 (flowState == kLinkUpFlow_None) ? "No" : 78 ((flowState == kLinkUpFlow_Symmetric) ? "Symmetric" : 79 ((flowState == kLinkUpFlow_PauseTxOnly) ? "Symmetric Sending" : 80 ((flowState == kLinkUpFlow_PauseRxOnly) ? "Asymmetric Receiving" : "unknnown"))), 81 (port) ? ", Port " : "", 82 (port) ? port : "", 83 phyregs[0], phyregs[1], phyregs[2], phyregs[3], phyregs[4], phyregs[5], 84 (loopback) ? ", Loopback " : "", 85 (loopback) ? loopback : ""); 86 87 IOLog("%s\n", buffer); 88} 89