if_nlge.c (212553) | if_nlge.c (212758) |
---|---|
1/*- 2 * Copyright (c) 2003-2009 RMI Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 31 unchanged lines hidden (view full) --- 40 * The XLS device supports upto 8 10/100/1000 Ethernet MACs or max 2 10G 41 * Ethernet MACs. The 1G MACs are of SGMII and 10G MACs are of XAUI 42 * interface. These ports are part of two network accelerators. 43 * The nlge driver configures and initializes non-SPI4 Ethernet ports in the 44 * XLR/XLS devices and enables data transfer on them. 45 */ 46 47#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003-2009 RMI Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 31 unchanged lines hidden (view full) --- 40 * The XLS device supports upto 8 10/100/1000 Ethernet MACs or max 2 10G 41 * Ethernet MACs. The 1G MACs are of SGMII and 10G MACs are of XAUI 42 * interface. These ports are part of two network accelerators. 43 * The nlge driver configures and initializes non-SPI4 Ethernet ports in the 44 * XLR/XLS devices and enables data transfer on them. 45 */ 46 47#include <sys/cdefs.h> |
48__FBSDID("$FreeBSD: head/sys/mips/rmi/dev/nlge/if_nlge.c 212553 2010-09-13 13:11:50Z jchandra $"); | 48__FBSDID("$FreeBSD: head/sys/mips/rmi/dev/nlge/if_nlge.c 212758 2010-09-16 19:13:55Z jchandra $"); |
49 50#ifdef HAVE_KERNEL_OPTION_HEADERS 51#include "opt_device_polling.h" 52#endif 53 54#include <sys/endian.h> 55#include <sys/systm.h> 56#include <sys/sockio.h> --- 238 unchanged lines hidden (view full) --- 295static devclass_t nlge_devclass; 296 297DRIVER_MODULE(nlna, iodi, nlna_driver, nlna_devclass, 0, 0); 298DRIVER_MODULE(nlge, nlna, nlge_driver, nlge_devclass, 0, 0); 299DRIVER_MODULE(miibus, nlge, miibus_driver, miibus_devclass, 0, 0); 300 301static uma_zone_t nl_tx_desc_zone; 302 | 49 50#ifdef HAVE_KERNEL_OPTION_HEADERS 51#include "opt_device_polling.h" 52#endif 53 54#include <sys/endian.h> 55#include <sys/systm.h> 56#include <sys/sockio.h> --- 238 unchanged lines hidden (view full) --- 295static devclass_t nlge_devclass; 296 297DRIVER_MODULE(nlna, iodi, nlna_driver, nlna_devclass, 0, 0); 298DRIVER_MODULE(nlge, nlna, nlge_driver, nlge_devclass, 0, 0); 299DRIVER_MODULE(miibus, nlge, miibus_driver, miibus_devclass, 0, 0); 300 301static uma_zone_t nl_tx_desc_zone; 302 |
303/* Function to atomically increment an integer with the given value. */ 304static __inline__ unsigned int 305ldadd_wu(unsigned int value, unsigned long *addr) | 303static __inline void 304atomic_incr_long(unsigned long *addr) |
306{ | 305{ |
307 __asm__ __volatile__( ".set push\n" 308 ".set noreorder\n" 309 "move $8, %2\n" 310 "move $9, %3\n" 311 /* "ldaddwu $8, $9\n" */ 312 ".word 0x71280011\n" 313 "move %0, $8\n" 314 ".set pop\n" 315 : "=&r"(value), "+m"(*addr) 316 : "0"(value), "r" ((unsigned long)addr) 317 : "$8", "$9"); 318 return value; 319} | 306 /* XXX: fix for 64 bit */ 307 unsigned int *iaddr = (unsigned int *)addr; |
320 | 308 |
321static __inline__ uint32_t 322xlr_enable_kx(void) 323{ 324 uint32_t sr = mips_rd_status(); 325 326 mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX); 327 return sr; | 309 xlr_ldaddwu(1, iaddr); |
328} 329 330static int 331nlna_probe(device_t dev) 332{ 333 return (BUS_PROBE_DEFAULT); 334} 335 --- 342 unchanged lines hidden (view full) --- 678 } else { 679 m_freem((struct mbuf *)(uintptr_t)phys_addr); 680 } 681 682 ifp = sc->nlge_if; 683 if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ 684 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 685 } | 310} 311 312static int 313nlna_probe(device_t dev) 314{ 315 return (BUS_PROBE_DEFAULT); 316} 317 --- 342 unchanged lines hidden (view full) --- 660 } else { 661 m_freem((struct mbuf *)(uintptr_t)phys_addr); 662 } 663 664 ifp = sc->nlge_if; 665 if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ 666 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 667 } |
686 ldadd_wu(1, (tx_error) ? &ifp->if_oerrors: &ifp->if_opackets); | 668 atomic_incr_long((tx_error) ? &ifp->if_oerrors: &ifp->if_opackets); |
687 } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { 688 /* Rx Packet */ 689 690 nlge_rx(sc, phys_addr, length); 691 nlna_submit_rx_free_desc(na_sc, 1); /* return free descr to NA */ 692 } else { 693 printf("[%s]: unrecognized ctrl=%d!\n", __FUNCTION__, ctrl); 694 } --- 66 unchanged lines hidden (view full) --- 761 * able to add to it not invoke nlge_start to drian the 762 * queue. The driver may have to do something in addition 763 * to reset'ing the OACTIVE bit when a trasnmit free-back 764 * is received. 765 */ 766 //ifp->if_drv_flags |= IFF_DRV_OACTIVE; 767 //IF_PREPEND(&ifp->if_snd, m); 768 m_freem(m); | 669 } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { 670 /* Rx Packet */ 671 672 nlge_rx(sc, phys_addr, length); 673 nlna_submit_rx_free_desc(na_sc, 1); /* return free descr to NA */ 674 } else { 675 printf("[%s]: unrecognized ctrl=%d!\n", __FUNCTION__, ctrl); 676 } --- 66 unchanged lines hidden (view full) --- 743 * able to add to it not invoke nlge_start to drian the 744 * queue. The driver may have to do something in addition 745 * to reset'ing the OACTIVE bit when a trasnmit free-back 746 * is received. 747 */ 748 //ifp->if_drv_flags |= IFF_DRV_OACTIVE; 749 //IF_PREPEND(&ifp->if_snd, m); 750 m_freem(m); |
769 ldadd_wu(1, &ifp->if_iqdrops); | 751 atomic_incr_long(&ifp->if_iqdrops); |
770 } 771 return; 772} 773 774static void 775nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len) 776{ | 752 } 753 return; 754} 755 756static void 757nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len) 758{ |
777 struct ifnet *ifp; 778 struct mbuf *m; 779 uint32_t tm, mag, sr; | 759 struct ifnet *ifp; 760 struct mbuf *m; 761 uint64_t tm, mag; 762 uint32_t sr; |
780 781 sr = xlr_enable_kx(); | 763 764 sr = xlr_enable_kx(); |
782 tm = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE); 783 mag = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + sizeof(uint32_t)); 784 mips_wr_status(sr); | 765 tm = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE); 766 mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t)); 767 xlr_restore_kx(sr); |
785 786 m = (struct mbuf *)(intptr_t)tm; 787 if (mag != 0xf00bad) { 788 /* somebody else's packet. Error - FIXME in intialization */ 789 printf("cpu %d: *ERROR* Not my packet paddr %llx\n", 790 xlr_core_id(), (uint64_t) paddr); 791 return; 792 } 793 794 ifp = sc->nlge_if; 795 /* align the data */ 796 m->m_data += BYTE_OFFSET; 797 m->m_pkthdr.len = m->m_len = len; 798 m->m_pkthdr.rcvif = ifp; 799 | 768 769 m = (struct mbuf *)(intptr_t)tm; 770 if (mag != 0xf00bad) { 771 /* somebody else's packet. Error - FIXME in intialization */ 772 printf("cpu %d: *ERROR* Not my packet paddr %llx\n", 773 xlr_core_id(), (uint64_t) paddr); 774 return; 775 } 776 777 ifp = sc->nlge_if; 778 /* align the data */ 779 m->m_data += BYTE_OFFSET; 780 m->m_pkthdr.len = m->m_len = len; 781 m->m_pkthdr.rcvif = ifp; 782 |
800 ldadd_wu(1, &ifp->if_ipackets); | 783 atomic_incr_long(&ifp->if_ipackets); |
801 (*ifp->if_input)(ifp, m); 802} 803 804static int 805nlge_mii_write(struct device *dev, int phyaddr, int regidx, int regval) 806{ 807 struct nlge_softc *sc; 808 --- 1081 unchanged lines hidden (view full) --- 1890 1891 while (len) { 1892 if (msg_sz == (FMN_SZ - 1)) { 1893 p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT); 1894 if (p2p == NULL) { 1895 return 2; 1896 } 1897 /* | 784 (*ifp->if_input)(ifp, m); 785} 786 787static int 788nlge_mii_write(struct device *dev, int phyaddr, int regidx, int regval) 789{ 790 struct nlge_softc *sc; 791 --- 1081 unchanged lines hidden (view full) --- 1873 1874 while (len) { 1875 if (msg_sz == (FMN_SZ - 1)) { 1876 p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT); 1877 if (p2p == NULL) { 1878 return 2; 1879 } 1880 /* |
1898 * As we currently use xlr_paddr_lw on a 32-bit 1899 * OS, both the pointers are laid out in one 1900 * 64-bit location - this makes it easy to 1901 * retrieve the pointers when processing the 1902 * tx free-back descriptor. | 1881 * Save the virtual address in the descriptor, 1882 * it makes freeing easy. |
1903 */ 1904 p2p->frag[XLR_MAX_TX_FRAGS] = | 1883 */ 1884 p2p->frag[XLR_MAX_TX_FRAGS] = |
1905 (((uint64_t) (vm_offset_t) p2p) << 32) | 1906 ((vm_offset_t) mbuf_chain); | 1885 (uint64_t)(vm_offset_t)p2p; |
1907 cur_p2d = &p2p->frag[0]; 1908 is_p2p = 1; 1909 } else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) { 1910 uma_zfree(nl_tx_desc_zone, p2p); 1911 return 1; 1912 } 1913 paddr = vtophys(buf); 1914 frag_sz = PAGE_SIZE - (buf & PAGE_MASK); --- 12 unchanged lines hidden (view full) --- 1927 if (msg_sz == 0) { 1928 printf("Zero-length mbuf chain ??\n"); 1929 *n_entries = msg_sz ; 1930 return 0; 1931 } 1932 1933 cur_p2d[-1] |= (1ULL << 63); /* set eop in most-recent p2d */ 1934 *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | | 1886 cur_p2d = &p2p->frag[0]; 1887 is_p2p = 1; 1888 } else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) { 1889 uma_zfree(nl_tx_desc_zone, p2p); 1890 return 1; 1891 } 1892 paddr = vtophys(buf); 1893 frag_sz = PAGE_SIZE - (buf & PAGE_MASK); --- 12 unchanged lines hidden (view full) --- 1906 if (msg_sz == 0) { 1907 printf("Zero-length mbuf chain ??\n"); 1908 *n_entries = msg_sz ; 1909 return 0; 1910 } 1911 1912 cur_p2d[-1] |= (1ULL << 63); /* set eop in most-recent p2d */ 1913 *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | |
1935 (vm_offset_t) mbuf_chain; | 1914 (vm_offset_t) mbuf_chain; /* XXX: fix 64 bit */ |
1936 *tx_desc = p2p; 1937 1938 if (is_p2p) { 1939 paddr = vtophys(p2p); 1940 p2p_sz++; 1941 fmn_msg->msg3 = (1ULL << 62) | ((uint64_t)fb_stn_id << 54) | 1942 ((uint64_t)(p2p_sz * 8) << 40) | paddr; 1943 *n_entries = FMN_SZ; --- 24 unchanged lines hidden (view full) --- 1968 return (0); 1969} 1970 1971static void 1972release_tx_desc(vm_paddr_t paddr) 1973{ 1974 struct nlge_tx_desc *tx_desc; 1975 uint32_t sr; | 1915 *tx_desc = p2p; 1916 1917 if (is_p2p) { 1918 paddr = vtophys(p2p); 1919 p2p_sz++; 1920 fmn_msg->msg3 = (1ULL << 62) | ((uint64_t)fb_stn_id << 54) | 1921 ((uint64_t)(p2p_sz * 8) << 40) | paddr; 1922 *n_entries = FMN_SZ; --- 24 unchanged lines hidden (view full) --- 1947 return (0); 1948} 1949 1950static void 1951release_tx_desc(vm_paddr_t paddr) 1952{ 1953 struct nlge_tx_desc *tx_desc; 1954 uint32_t sr; |
1976 uint32_t val1, val2; | 1955 uint64_t vaddr; |
1977 1978 paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); 1979 sr = xlr_enable_kx(); | 1956 1957 paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); 1958 sr = xlr_enable_kx(); |
1980 val1 = xlr_paddr_lw(paddr); 1981 paddr += sizeof(void *); 1982 val2 = xlr_paddr_lw(paddr); 1983 mips_wr_status(sr); | 1959 vaddr = xlr_paddr_ld(paddr); 1960 xlr_restore_kx(sr); |
1984 | 1961 |
1985 tx_desc = (struct nlge_tx_desc*)(intptr_t) val1; | 1962 tx_desc = (struct nlge_tx_desc*)(intptr_t)vaddr; |
1986 uma_zfree(nl_tx_desc_zone, tx_desc); 1987} 1988 1989static void * 1990get_buf(void) 1991{ | 1963 uma_zfree(nl_tx_desc_zone, tx_desc); 1964} 1965 1966static void * 1967get_buf(void) 1968{ |
1992 struct mbuf *m_new; 1993 vm_paddr_t temp1, temp2; 1994 unsigned int *md; | 1969 struct mbuf *m_new; 1970 uint64_t *md; 1971#ifdef INVARIANTS 1972 vm_paddr_t temp1, temp2; 1973#endif |
1995 1996 if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) | 1974 1975 if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) |
1997 return NULL; | 1976 return (NULL); |
1998 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1999 m_adj(m_new, XLR_CACHELINE_SIZE - ((unsigned int)m_new->m_data & 0x1f)); | 1977 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1978 m_adj(m_new, XLR_CACHELINE_SIZE - ((unsigned int)m_new->m_data & 0x1f)); |
2000 md = (unsigned int *)m_new->m_data; 2001 md[0] = (unsigned int)m_new; /* Back Ptr */ | 1979 md = (uint64_t *)m_new->m_data; 1980 md[0] = (intptr_t)m_new; /* Back Ptr */ |
2002 md[1] = 0xf00bad; 2003 m_adj(m_new, XLR_CACHELINE_SIZE); 2004 | 1981 md[1] = 0xf00bad; 1982 m_adj(m_new, XLR_CACHELINE_SIZE); 1983 |
1984#ifdef INVARIANTS |
|
2005 temp1 = vtophys((vm_offset_t) m_new->m_data); 2006 temp2 = vtophys((vm_offset_t) m_new->m_data + 1536); 2007 if ((temp1 + 1536) != temp2) 2008 panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); | 1985 temp1 = vtophys((vm_offset_t) m_new->m_data); 1986 temp2 = vtophys((vm_offset_t) m_new->m_data + 1536); 1987 if ((temp1 + 1536) != temp2) 1988 panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); |
1989#endif |
|
2009 2010 return ((void *)m_new->m_data); 2011} 2012 2013static int 2014nlge_gmac_config_speed(struct nlge_softc *sc, int quick) 2015{ 2016 struct mii_data *md; --- 382 unchanged lines hidden --- | 1990 1991 return ((void *)m_new->m_data); 1992} 1993 1994static int 1995nlge_gmac_config_speed(struct nlge_softc *sc, int quick) 1996{ 1997 struct mii_data *md; --- 382 unchanged lines hidden --- |