summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/gssapi/generic/gssapi_ext.h1
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c126
-rw-r--r--src/lib/gssapi/generic/oid_ops.c1
-rw-r--r--src/lib/gssapi/krb5/import_name.c5
-rw-r--r--src/lib/gssapi/krb5/inq_names.c4
-rw-r--r--src/lib/gssapi/libgssapi_krb5.exports1
-rw-r--r--src/lib/gssapi/mechglue/g_imp_name.c2
7 files changed, 78 insertions, 62 deletions
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
index 05f1ed7fb4..dd12ffecbf 100644
--- a/src/lib/gssapi/generic/gssapi_ext.h
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -368,6 +368,7 @@ gss_add_cred_impersonate_name(
* Naming extensions
*/
GSS_DLLIMP extern gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER;
+GSS_DLLIMP extern gss_OID GSS_C_NT_COMPOSITE_EXPORT;
OM_uint32 KRB5_CALLCONV gss_display_name_ext
(
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
index 4718ac73a8..4759cdef83 100644
--- a/src/lib/gssapi/generic/gssapi_generic.c
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -119,7 +119,13 @@ static const gss_OID_desc const_oids[] = {
* GSS_C_NT_EXPORT_NAME should be initialized to point
* to that gss_OID_desc.
*/
-
+ {6, (void *)"\x2b\x06\x01\x05\x06\x06"},
+ /* corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 6(gss-composite-export)}. The constant
+ * GSS_C_NT_COMPOSITE_EXPORT should be initialized to point
+ * to that gss_OID_desc.
+ */
/* GSS_C_INQ_SSPI_SESSION_KEY 1.2.840.113554.1.2.2.5.5 */
{11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"},
@@ -180,37 +186,39 @@ GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS = oids+5;
GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME = oids+6;
gss_OID gss_nt_exported_name = oids+6;
-GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY = oids+7;
-
-GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_CONCRETE = oids+8;
-GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_PSEUDO = oids+9;
-GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_COMPOSITE = oids+10;
-GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_NEGO = oids+11;
-GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_GLUE = oids+12;
-GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_MECH = oids+13;
-GSS_DLLIMP gss_const_OID GSS_C_MA_DEPRECATED = oids+14;
-GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_DFLT_MECH = oids+15;
-GSS_DLLIMP gss_const_OID GSS_C_MA_ITOK_FRAMED = oids+16;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT = oids+17;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG = oids+18;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_INIT = oids+19;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_INIT = oids+20;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_ANON = oids+21;
-GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_ANON = oids+22;
-GSS_DLLIMP gss_const_OID GSS_C_MA_DELEG_CRED = oids+23;
-GSS_DLLIMP gss_const_OID GSS_C_MA_INTEG_PROT = oids+24;
-GSS_DLLIMP gss_const_OID GSS_C_MA_CONF_PROT = oids+25;
-GSS_DLLIMP gss_const_OID GSS_C_MA_MIC = oids+26;
-GSS_DLLIMP gss_const_OID GSS_C_MA_WRAP = oids+27;
-GSS_DLLIMP gss_const_OID GSS_C_MA_PROT_READY = oids+28;
-GSS_DLLIMP gss_const_OID GSS_C_MA_REPLAY_DET = oids+29;
-GSS_DLLIMP gss_const_OID GSS_C_MA_OOS_DET = oids+30;
-GSS_DLLIMP gss_const_OID GSS_C_MA_CBINDINGS = oids+31;
-GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+32;
-GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+33;
-GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+34;
-
-static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+8 };
+GSS_DLLIMP gss_OID GSS_C_NT_COMPOSITE_EXPORT = oids+7;
+
+GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY = oids+8;
+
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_CONCRETE = oids+9;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_PSEUDO = oids+10;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_COMPOSITE = oids+11;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_NEGO = oids+12;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_GLUE = oids+13;
+GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_MECH = oids+14;
+GSS_DLLIMP gss_const_OID GSS_C_MA_DEPRECATED = oids+15;
+GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_DFLT_MECH = oids+16;
+GSS_DLLIMP gss_const_OID GSS_C_MA_ITOK_FRAMED = oids+17;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT = oids+18;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG = oids+19;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_INIT = oids+20;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_INIT = oids+21;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_ANON = oids+22;
+GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_ANON = oids+23;
+GSS_DLLIMP gss_const_OID GSS_C_MA_DELEG_CRED = oids+24;
+GSS_DLLIMP gss_const_OID GSS_C_MA_INTEG_PROT = oids+25;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CONF_PROT = oids+26;
+GSS_DLLIMP gss_const_OID GSS_C_MA_MIC = oids+27;
+GSS_DLLIMP gss_const_OID GSS_C_MA_WRAP = oids+28;
+GSS_DLLIMP gss_const_OID GSS_C_MA_PROT_READY = oids+29;
+GSS_DLLIMP gss_const_OID GSS_C_MA_REPLAY_DET = oids+30;
+GSS_DLLIMP gss_const_OID GSS_C_MA_OOS_DET = oids+31;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CBINDINGS = oids+32;
+GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33;
+GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34;
+GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35;
+
+static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 };
gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc;
#define STRING_BUFFER(x) { sizeof((x) - 1), (x) }
@@ -222,174 +230,174 @@ static struct mech_attr_info_desc {
gss_buffer_desc long_desc;
} mech_attr_info[] = {
{
- oids+8,
+ oids+9,
STRING_BUFFER("GSS_C_MA_MECH_CONCRETE"),
STRING_BUFFER("concrete-mech"),
STRING_BUFFER("Mechanism is neither a pseudo-mechanism nor a "
"composite mechanism."),
},
{
- oids+9,
+ oids+10,
STRING_BUFFER("GSS_C_MA_MECH_PSEUDO"),
STRING_BUFFER("pseudo-mech"),
STRING_BUFFER("Mechanism is a pseudo-mechanism."),
},
{
- oids+10,
+ oids+11,
STRING_BUFFER("GSS_C_MA_MECH_COMPOSITE"),
STRING_BUFFER("composite-mech"),
STRING_BUFFER("Mechanism is a composite of other mechanisms."),
},
{
- oids+11,
+ oids+12,
STRING_BUFFER("GSS_C_MA_MECH_NEGO"),
STRING_BUFFER("mech-negotiation-mech"),
STRING_BUFFER("Mechanism negotiates other mechanisms."),
},
{
- oids+12,
+ oids+13,
STRING_BUFFER("GSS_C_MA_MECH_GLUE"),
STRING_BUFFER("mech-glue"),
STRING_BUFFER("OID is not a mechanism but the GSS-API itself."),
},
{
- oids+13,
+ oids+14,
STRING_BUFFER("GSS_C_MA_NOT_MECH"),
STRING_BUFFER("not-mech"),
STRING_BUFFER("Known OID but not a mechanism OID."),
},
{
- oids+14,
+ oids+15,
STRING_BUFFER("GSS_C_MA_DEPRECATED"),
STRING_BUFFER("mech-deprecated"),
STRING_BUFFER("Mechanism is deprecated."),
},
{
- oids+15,
+ oids+16,
STRING_BUFFER("GSS_C_MA_NOT_DFLT_MECH"),
STRING_BUFFER("mech-not-default"),
STRING_BUFFER("Mechanism must not be used as a default mechanism."),
},
{
- oids+16,
+ oids+17,
STRING_BUFFER("GSS_C_MA_ITOK_FRAMED"),
STRING_BUFFER("initial-is-framed"),
STRING_BUFFER("Mechanism's initial contexts are properly framed."),
},
{
- oids+17,
+ oids+18,
STRING_BUFFER("GSS_C_MA_AUTH_INIT"),
STRING_BUFFER("auth-init-princ"),
STRING_BUFFER("Mechanism supports authentication of initiator to "
"acceptor."),
},
{
- oids+18,
+ oids+19,
STRING_BUFFER("GSS_C_MA_AUTH_TARG"),
STRING_BUFFER("auth-targ-princ"),
STRING_BUFFER("Mechanism supports authentication of acceptor to "
"initiator."),
},
{
- oids+19,
+ oids+20,
STRING_BUFFER("GSS_C_MA_AUTH_INIT_INIT"),
STRING_BUFFER("auth-init-princ-initial"),
STRING_BUFFER("Mechanism supports authentication of initiator using "
"initial credentials."),
},
{
- oids+20,
+ oids+21,
STRING_BUFFER("GSS_C_MA_AUTH_TARG_INIT"),
STRING_BUFFER("auth-target-princ-initial"),
STRING_BUFFER("Mechanism supports authentication of acceptor using "
"initial credentials."),
},
{
- oids+21,
+ oids+22,
STRING_BUFFER("GSS_C_MA_AUTH_INIT_ANON"),
STRING_BUFFER("auth-init-princ-anon"),
STRING_BUFFER("Mechanism supports GSS_C_NT_ANONYMOUS as an initiator "
"name."),
},
{
- oids+22,
+ oids+23,
STRING_BUFFER("GSS_C_MA_AUTH_TARG_ANON"),
STRING_BUFFER("auth-targ-princ-anon"),
STRING_BUFFER("Mechanism supports GSS_C_NT_ANONYMOUS as an acceptor "
"name."),
},
{
- oids+23,
+ oids+24,
STRING_BUFFER("GSS_C_MA_DELEG_CRED"),
STRING_BUFFER("deleg-cred"),
STRING_BUFFER("Mechanism supports credential delegation."),
},
{
- oids+24,
+ oids+25,
STRING_BUFFER("GSS_C_MA_INTEG_PROT"),
STRING_BUFFER("integ-prot"),
STRING_BUFFER("Mechanism supports per-message integrity protection."),
},
{
- oids+25,
+ oids+26,
STRING_BUFFER("GSS_C_MA_CONF_PROT"),
STRING_BUFFER("conf-prot"),
STRING_BUFFER("Mechanism supports per-message confidentiality "
"protection."),
},
{
- oids+26,
+ oids+27,
STRING_BUFFER("GSS_C_MA_MIC"),
STRING_BUFFER("mic"),
STRING_BUFFER("Mechanism supports Message Integrity Code (MIC) "
"tokens."),
},
{
- oids+27,
+ oids+28,
STRING_BUFFER("GSS_C_MA_WRAP"),
STRING_BUFFER("wrap"),
STRING_BUFFER("Mechanism supports wrap tokens."),
},
{
- oids+28,
+ oids+29,
STRING_BUFFER("GSS_C_MA_PROT_READY"),
STRING_BUFFER("prot-ready"),
STRING_BUFFER("Mechanism supports per-message proteciton prior to "
"full context establishment."),
},
{
- oids+29,
+ oids+30,
STRING_BUFFER("GSS_C_MA_REPLAY_DET"),
STRING_BUFFER("replay-detection"),
STRING_BUFFER("Mechanism supports replay detection."),
},
{
- oids+30,
+ oids+31,
STRING_BUFFER("GSS_C_MA_OOS_DET"),
STRING_BUFFER("oos-detection"),
STRING_BUFFER("Mechanism supports out-of-sequence detection."),
},
{
- oids+31,
+ oids+32,
STRING_BUFFER("GSS_C_MA_CBINDINGS"),
STRING_BUFFER("channel-bindings"),
STRING_BUFFER("Mechanism supports channel bindings."),
},
{
- oids+32,
+ oids+33,
STRING_BUFFER("GSS_C_MA_PFS"),
STRING_BUFFER("pfs"),
STRING_BUFFER("Mechanism supports Perfect Forward Security."),
},
{
- oids+33,
+ oids+34,
STRING_BUFFER("GSS_C_MA_COMPRESS"),
STRING_BUFFER("compress"),
STRING_BUFFER("Mechanism supports compression of data inputs to "
"gss_wrap()."),
},
{
- oids+34,
+ oids+35,
STRING_BUFFER("GSS_C_MA_CTX_TRANS"),
STRING_BUFFER("context-transfer"),
STRING_BUFFER("Mechanism supports security context export/import."),
diff --git a/src/lib/gssapi/generic/oid_ops.c b/src/lib/gssapi/generic/oid_ops.c
index 665b5902f4..85584fc3bd 100644
--- a/src/lib/gssapi/generic/oid_ops.c
+++ b/src/lib/gssapi/generic/oid_ops.c
@@ -97,6 +97,7 @@ generic_gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
(*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
(*oid != GSS_C_NT_ANONYMOUS) &&
(*oid != GSS_C_NT_EXPORT_NAME) &&
+ (*oid != GSS_C_NT_COMPOSITE_EXPORT) &&
(*oid != gss_nt_service_name)) {
free((*oid)->elements);
free(*oid);
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
index 0e730f98e2..ebc2a7bbea 100644
--- a/src/lib/gssapi/krb5/import_name.c
+++ b/src/lib/gssapi/krb5/import_name.c
@@ -218,7 +218,8 @@ krb5_gss_import_name(minor_status, input_name_buffer,
uid = atoi(tmp);
goto do_getpwuid;
#endif
- } else if (g_OID_equal(input_name_type, gss_nt_exported_name)) {
+ } else if (g_OID_equal(input_name_type, gss_nt_exported_name) ||
+ g_OID_equal(input_name_type, GSS_C_NT_COMPOSITE_EXPORT)) {
#define BOUNDS_CHECK(cp, end, n) \
do { if ((end) - (cp) < (n)) goto fail_name; } while (0)
cp = (unsigned char *)tmp;
@@ -231,7 +232,7 @@ krb5_gss_import_name(minor_status, input_name_buffer,
case 0x01:
break;
case 0x02:
- has_ad++;
+ has_ad++; /* is composite name */
break;
default:
goto fail_name;
diff --git a/src/lib/gssapi/krb5/inq_names.c b/src/lib/gssapi/krb5/inq_names.c
index 9cc43500f4..fcf7dbcd3a 100644
--- a/src/lib/gssapi/krb5/inq_names.c
+++ b/src/lib/gssapi/krb5/inq_names.c
@@ -77,6 +77,10 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types)
((major = generic_gss_add_oid_set_member(minor_status,
gss_nt_krb5_name,
name_types)
+ ) == GSS_S_COMPLETE) &&
+ ((major = generic_gss_add_oid_set_member(minor_status,
+ GSS_C_NT_COMPOSITE_EXPORT,
+ name_types)
) == GSS_S_COMPLETE)
) {
major = generic_gss_add_oid_set_member(minor_status,
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index a8ee3f2447..3da3a237c4 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -1,6 +1,7 @@
GSS_C_ATTR_LOCAL_LOGIN_USER
GSS_C_INQ_SSPI_SESSION_KEY
GSS_C_NT_ANONYMOUS
+GSS_C_NT_COMPOSITE_EXPORT
GSS_C_NT_EXPORT_NAME
GSS_C_NT_HOSTBASED_SERVICE
GSS_C_NT_HOSTBASED_SERVICE_X
diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c
index 7afa188e53..8fcc3d0f26 100644
--- a/src/lib/gssapi/mechglue/g_imp_name.c
+++ b/src/lib/gssapi/mechglue/g_imp_name.c
@@ -209,7 +209,7 @@ importExportName(minor, unionName)
buf = (unsigned char *)expName.value;
if (buf[0] != 0x04)
return (GSS_S_DEFECTIVE_TOKEN);
- if (buf[1] != 0x01 && buf[1] != 0x02)
+ if (buf[1] != 0x01 && buf[1] != 0x02) /* allow composite names */
return (GSS_S_DEFECTIVE_TOKEN);
buf += expNameTokIdLen;
s="hl kwd">dm9000_phy_write(int, u16); static u8 DM9000_ior(int); static void DM9000_iow(int reg, u8 value); /* DM9000 network board routine ---------------------------- */ #ifndef CONFIG_DM9000_BYTE_SWAPPED #define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r)) #define DM9000_outw(d,r) writew(d, (volatile u16 *)(r)) #define DM9000_outl(d,r) writel(d, (volatile u32 *)(r)) #define DM9000_inb(r) readb((volatile u8 *)(r)) #define DM9000_inw(r) readw((volatile u16 *)(r)) #define DM9000_inl(r) readl((volatile u32 *)(r)) #else #define DM9000_outb(d, r) __raw_writeb(d, r) #define DM9000_outw(d, r) __raw_writew(d, r) #define DM9000_outl(d, r) __raw_writel(d, r) #define DM9000_inb(r) __raw_readb(r) #define DM9000_inw(r) __raw_readw(r) #define DM9000_inl(r) __raw_readl(r) #endif #ifdef CONFIG_DM9000_DEBUG static void dump_regs(void) { DM9000_DBG("\n"); DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); DM9000_DBG("\n"); } #endif static void dm9000_outblk_8bit(volatile void *data_ptr, int count) { int i; for (i = 0; i < count; i++) DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); } static void dm9000_outblk_16bit(volatile void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; for (i = 0; i < tmplen; i++) DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); } static void dm9000_outblk_32bit(volatile void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; for (i = 0; i < tmplen; i++) DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); } static void dm9000_inblk_8bit(void *data_ptr, int count) { int i; for (i = 0; i < count; i++) ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA); } static void dm9000_inblk_16bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; for (i = 0; i < tmplen; i++) ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA); } static void dm9000_inblk_32bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; for (i = 0; i < tmplen; i++) ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA); } static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) { u32 tmpdata; DM9000_outb(DM9000_MRCMD, DM9000_IO); tmpdata = DM9000_inl(DM9000_DATA); *RxStatus = __le16_to_cpu(tmpdata); *RxLen = __le16_to_cpu(tmpdata >> 16); } static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen) { DM9000_outb(DM9000_MRCMD, DM9000_IO); *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA)); *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA)); } static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen) { DM9000_outb(DM9000_MRCMD, DM9000_IO); *RxStatus = __le16_to_cpu(DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8)); *RxLen = __le16_to_cpu(DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8)); } /* Search DM9000 board, allocate space and register it */ int dm9000_probe(void) { u32 id_val; id_val = DM9000_ior(DM9000_VIDL); id_val |= DM9000_ior(DM9000_VIDH) << 8; id_val |= DM9000_ior(DM9000_PIDL) << 16; id_val |= DM9000_ior(DM9000_PIDH) << 24; if (id_val == DM9000_ID) { printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE, id_val); return 0; } else { printf("dm9000 not found at 0x%08x id: 0x%08x\n", CONFIG_DM9000_BASE, id_val); return -1; } } /* General Purpose dm9000 reset routine */ static void dm9000_reset(void) { DM9000_DBG("resetting DM9000\n"); /* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ /* DEBUG: Make all GPIO0 outputs, all others inputs */ DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT); /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ DM9000_iow(DM9000_GPR, 0); /* Step 2: Software reset */ DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); do { DM9000_DBG("resetting the DM9000, 1st reset\n"); udelay(25); /* Wait at least 20 us */ } while (DM9000_ior(DM9000_NCR) & 1); DM9000_iow(DM9000_NCR, 0); DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */ do { DM9000_DBG("resetting the DM9000, 2nd reset\n"); udelay(25); /* Wait at least 20 us */ } while (DM9000_ior(DM9000_NCR) & 1); /* Check whether the ethernet controller is present */ if ((DM9000_ior(DM9000_PIDL) != 0x0) || (DM9000_ior(DM9000_PIDH) != 0x90)) printf("ERROR: resetting DM9000 -> not responding\n"); } /* Initialize dm9000 board */ static int dm9000_init(struct eth_device *dev, struct bd_info *bd) { int i, oft, lnk; u8 io_mode; struct board_info *db = &dm9000_info; DM9000_DBG("%s\n", __func__); /* RESET device */ dm9000_reset(); if (dm9000_probe() < 0) return -1; /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ io_mode = DM9000_ior(DM9000_ISR) >> 6; switch (io_mode) { case 0x0: /* 16-bit mode */ printf("DM9000: running in 16 bit mode\n"); db->outblk = dm9000_outblk_16bit; db->inblk = dm9000_inblk_16bit; db->rx_status = dm9000_rx_status_16bit; break; case 0x01: /* 32-bit mode */ printf("DM9000: running in 32 bit mode\n"); db->outblk = dm9000_outblk_32bit; db->inblk = dm9000_inblk_32bit; db->rx_status = dm9000_rx_status_32bit; break; case 0x02: /* 8 bit mode */ printf("DM9000: running in 8 bit mode\n"); db->outblk = dm9000_outblk_8bit; db->inblk = dm9000_inblk_8bit; db->rx_status = dm9000_rx_status_8bit; break; default: /* Assume 8 bit mode, will probably not work anyway */ printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); db->outblk = dm9000_outblk_8bit; db->inblk = dm9000_inblk_8bit; db->rx_status = dm9000_rx_status_8bit; break; } /* Program operating register, only internal phy supported */ DM9000_iow(DM9000_NCR, 0x0); /* TX Polling clear */ DM9000_iow(DM9000_TCR, 0); /* Less 3Kb, 200us */ DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); /* Flow Control : High/Low Water */ DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* SH FIXME: This looks strange! Flow Control */ DM9000_iow(DM9000_FCR, 0x0); /* Special Mode */ DM9000_iow(DM9000_SMCR, 0); /* clear TX status */ DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* Clear interrupt status */ DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); printf("MAC: %pM\n", dev->enetaddr); if (!is_valid_ethaddr(dev->enetaddr)) { printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); } /* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) DM9000_iow(oft, dev->enetaddr[i]); for (i = 0, oft = 0x16; i < 8; i++, oft++) DM9000_iow(oft, 0xff); /* read back mac, just to be sure */ for (i = 0, oft = 0x10; i < 6; i++, oft++) DM9000_DBG("%02x:", DM9000_ior(oft)); DM9000_DBG("\n"); /* Activate DM9000 */ /* RX enable */ DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* Enable TX/RX interrupt mask */ DM9000_iow(DM9000_IMR, IMR_PAR); i = 0; while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */ udelay(1000); i++; if (i == 10000) { printf("could not establish link\n"); return 0; } } /* see what we've got */ lnk = dm9000_phy_read(17) >> 12; printf("operating at "); switch (lnk) { case 1: printf("10M half duplex "); break; case 2: printf("10M full duplex "); break; case 4: printf("100M half duplex "); break; case 8: printf("100M full duplex "); break; default: printf("unknown: %d ", lnk); break; } printf("mode\n"); return 0; } /* Hardware start transmission. Send a packet to media from the upper layer. */ static int dm9000_send(struct eth_device *netdev, void *packet, int length) { int tmo; struct board_info *db = &dm9000_info; DM9000_DMP_PACKET(__func__ , packet, length); DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ /* Move data to DM9000 TX RAM */ DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ /* push the data to the TX-fifo */ (db->outblk)(packet, length); /* Set TX length to DM9000 */ DM9000_iow(DM9000_TXPLL, length & 0xff); DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); /* Issue TX polling command */ DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ /* wait for end of transmission */ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { if (get_timer(0) >= tmo) { printf("transmission timeout\n"); break; } } DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ DM9000_DBG("transmit done\n\n"); return 0; } /* Stop the interface. The interface is stopped when it is brought. */ static void dm9000_halt(struct eth_device *netdev) { DM9000_DBG("%s\n", __func__); /* RESET devie */ dm9000_phy_write(0, 0x8000); /* PHY RESET */ DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */ DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */ DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */ } /* Received a packet and pass to upper layer */ static int dm9000_rx(struct eth_device *netdev) { u8 rxbyte; u8 *rdptr = (u8 *)net_rx_packets[0]; u16 RxStatus, RxLen = 0; struct board_info *db = &dm9000_info; /* Check packet ready or not, we must check the ISR status first for DM9000A */ if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ return 0; DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ /* There is _at least_ 1 package in the fifo, read them all */ for (;;) { DM9000_ior(DM9000_MRCMDX); /* Dummy read */ /* Get most updated data, only look at bits 0:1, See application notes DM9000 */ rxbyte = DM9000_inb(DM9000_DATA) & 0x03; /* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) { DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */