diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 23:48:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 23:48:34 +0000 |
commit | 7fd36ebeeec9244a7431bb010e6e3c5e4848a0d5 (patch) | |
tree | 5fb03a9aafdd1cec5f4f6ff7f1873174cb89b66c /drivers/net/skfp | |
parent | ba2dacab305c598cd4c34a604f8e276bf5bab5ff (diff) |
Merge with Linux 2.3.99-pre8. Linus must hate me, too man patches ;-)
Diffstat (limited to 'drivers/net/skfp')
-rw-r--r-- | drivers/net/skfp/fplustm.c | 28 | ||||
-rw-r--r-- | drivers/net/skfp/h/fplustm.h | 24 | ||||
-rw-r--r-- | drivers/net/skfp/h/osdef1st.h | 17 | ||||
-rw-r--r-- | drivers/net/skfp/h/smt.h | 114 | ||||
-rw-r--r-- | drivers/net/skfp/h/targetos.h | 11 | ||||
-rw-r--r-- | drivers/net/skfp/hwmtm.c | 52 | ||||
-rw-r--r-- | drivers/net/skfp/skfddi.c | 208 |
7 files changed, 295 insertions, 159 deletions
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c index 83a935791..f5bda2464 100644 --- a/drivers/net/skfp/fplustm.c +++ b/drivers/net/skfp/fplustm.c @@ -390,9 +390,9 @@ struct s_smc *smc ; outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ; } -void set_long(p,l) +void set_int(p,l) char *p; -long l; +int l; { p[0] = (char)(l >> 24) ; p[1] = (char)(l >> 16) ; @@ -416,12 +416,12 @@ unsigned off; /* start address within buffer memory */ int len ; /* lenght of the frame including the FC */ { int i ; - u_long *p ; + u_int *p ; CHECK_NPP() ; MARW(off) ; /* set memory address reg for writes */ - p = (u_long *) mac ; + p = (u_int *) mac ; for (i = (len + 3)/4 ; i ; i--) { if (i == 1) { /* last word, set the tag bit */ @@ -460,7 +460,7 @@ int len ; /* lenght of the frame including the FC */ static void directed_beacon(smc) struct s_smc *smc ; { - SK_LOC_DECL(u_long,a[2]) ; + SK_LOC_DECL(u_int,a[2]) ; /* * set UNA in frame @@ -491,7 +491,7 @@ static void build_claim_beacon(smc,t_request) struct s_smc *smc ; u_long t_request; { - u_long td ; + u_int td ; int len ; struct fddi_mac_sf *mac ; @@ -499,13 +499,13 @@ u_long t_request; * build claim packet */ len = 17 ; - td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ; + td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ; mac = &smc->hw.fp.mac_sfb ; mac->mac_fc = FC_CLAIM ; /* DA == SA in claim frame */ mac->mac_source = mac->mac_dest = MA ; /* 2's complement */ - set_long((char *)mac->mac_info,(long)t_request) ; + set_int((char *)mac->mac_info,(int)t_request) ; copy_tx_mac(smc,td,(struct fddi_mac *)mac, smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF,len) ; @@ -516,11 +516,11 @@ u_long t_request; * build beacon packet */ len = 17 ; - td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ; + td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ; mac->mac_fc = FC_BEACON ; mac->mac_source = MA ; mac->mac_dest = null_addr ; /* DA == 0 in beacon frame */ - set_long((char *) mac->mac_info,((long)BEACON_INFO<<24L) + 0 ) ; + set_int((char *) mac->mac_info,((int)BEACON_INFO<<24) + 0 ) ; copy_tx_mac(smc,td,(struct fddi_mac *)mac, smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF,len) ; @@ -532,13 +532,13 @@ u_long t_request; * contains optional UNA */ len = 23 ; - td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ; + td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ; mac->mac_fc = FC_BEACON ; mac->mac_source = MA ; mac->mac_dest = dbeacon_multi ; /* multicast */ - set_long((char *) mac->mac_info,((long)DBEACON_INFO<<24L) + 0 ) ; - set_long((char *) mac->mac_info+4,0L) ; - set_long((char *) mac->mac_info+8,0L) ; + set_int((char *) mac->mac_info,((int)DBEACON_INFO<<24) + 0 ) ; + set_int((char *) mac->mac_info+4,0) ; + set_int((char *) mac->mac_info+8,0) ; copy_tx_mac(smc,td,(struct fddi_mac *)mac, smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ; diff --git a/drivers/net/skfp/h/fplustm.h b/drivers/net/skfp/h/fplustm.h index 9e1ce036e..bb9f3b2ac 100644 --- a/drivers/net/skfp/h/fplustm.h +++ b/drivers/net/skfp/h/fplustm.h @@ -54,12 +54,12 @@ struct err_st { * Transmit Descriptor struct */ struct s_smt_fp_txd { - u_long txd_tbctrl ; /* transmit buffer control */ - u_long txd_txdscr ; /* transmit frame status word */ - u_long txd_tbadr ; /* physical tx buffer address */ - u_long txd_ntdadr ; /* physical pointer to the next TxD */ + u_int txd_tbctrl ; /* transmit buffer control */ + u_int txd_txdscr ; /* transmit frame status word */ + u_int txd_tbadr ; /* physical tx buffer address */ + u_int txd_ntdadr ; /* physical pointer to the next TxD */ #ifdef ENA_64BIT_SUP - u_long txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/ + u_int txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/ #endif char far *txd_virt ; /* virtual pointer to the data frag */ /* virt pointer to the next TxD */ @@ -71,12 +71,12 @@ struct s_smt_fp_txd { * Receive Descriptor struct */ struct s_smt_fp_rxd { - u_long rxd_rbctrl ; /* receive buffer control */ - u_long rxd_rfsw ; /* receive frame status word */ - u_long rxd_rbadr ; /* physical rx buffer address */ - u_long rxd_nrdadr ; /* physical pointer to the next RxD */ + u_int rxd_rbctrl ; /* receive buffer control */ + u_int rxd_rfsw ; /* receive frame status word */ + u_int rxd_rbadr ; /* physical rx buffer address */ + u_int rxd_nrdadr ; /* physical pointer to the next RxD */ #ifdef ENA_64BIT_SUP - u_long rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/ + u_int rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/ #endif char far *rxd_virt ; /* virtual pointer to the data frag */ /* virt pointer to the next RxD */ @@ -259,8 +259,10 @@ struct s_smt_fp { (((x)>> 8L)&0x0000ff00L) + \ (((x)>>24L)&0x000000ffL)) #else +#ifndef AIX_REVERSE #define AIX_REVERSE(x) (x) #endif +#endif #ifdef MDR_REV #define MDR_REVERSE(x) ((((x)<<24L)&0xff000000L) + \ @@ -268,7 +270,9 @@ struct s_smt_fp { (((x)>> 8L)&0x0000ff00L) + \ (((x)>>24L)&0x000000ffL)) #else +#ifndef MDR_REVERSE #define MDR_REVERSE(x) (x) #endif +#endif #endif diff --git a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h index 69f27707d..a6866248a 100644 --- a/drivers/net/skfp/h/osdef1st.h +++ b/drivers/net/skfp/h/osdef1st.h @@ -97,22 +97,27 @@ * * Note: The size of these structures must follow this rule: * - * size = 8 + n * 16, n >= 0 + * sizeof(struct) + 2*sizeof(void*) == n * 16, n >= 1 * - * NOTE: The size of this structures may not be changed, because - * libskfddi.a depends on it. But the dummy fields can be - * used freely. + * We use the dma_addr fields under Linux to keep track of the + * DMA address of the packet data, for later pci_unmap_single. -DaveM */ struct s_txd_os { // os-specific part of transmit descriptor struct sk_buff *skb; - long dummy; + dma_addr_t dma_addr; } ; struct s_rxd_os { // os-specific part of receive descriptor struct sk_buff *skb; - long dummy; + dma_addr_t dma_addr; } ; +/* + * So we do not need to make too many modifications to the generic driver + * parts, we take advantage of the AIX byte swapping macro interface. + */ +#define AIX_REVERSE(x) ((u32)le32_to_cpu((u32)(x))) +#define MDR_REVERSE(x) ((u32)le32_to_cpu((u32)(x))) diff --git a/drivers/net/skfp/h/smt.h b/drivers/net/skfp/h/smt.h index 08eb1ccbf..5a2606d16 100644 --- a/drivers/net/skfp/h/smt.h +++ b/drivers/net/skfp/h/smt.h @@ -53,7 +53,7 @@ _packed struct smt_header { u_char smt_class ; /* NIF, SIF ... */ u_char smt_type ; /* req., response .. */ u_short smt_version ; /* version id */ - u_long smt_tid ; /* transaction ID */ + u_int smt_tid ; /* transaction ID */ struct smt_sid smt_sid ; /* station ID */ u_short smt_pad ; /* pad with 0 */ u_short smt_len ; /* length of info field */ @@ -278,15 +278,15 @@ struct smt_p_mac_status { struct smt_para para ; /* generic parameter header */ u_short st_mib_index ; /* MIB index */ u_short st_mac_index ; /* n+1 .. n+m */ - u_long st_t_req ; /* T_Req */ - u_long st_t_neg ; /* T_Neg */ - u_long st_t_max ; /* T_Max */ - u_long st_tvx_value ; /* TVX_Value */ - u_long st_t_min ; /* T_Min */ - u_long st_sba ; /* synchr. bandwidth alloc */ - u_long st_frame_ct ; /* frame counter */ - u_long st_error_ct ; /* error counter */ - u_long st_lost_ct ; /* lost frames counter */ + u_int st_t_req ; /* T_Req */ + u_int st_t_neg ; /* T_Neg */ + u_int st_t_max ; /* T_Max */ + u_int st_tvx_value ; /* TVX_Value */ + u_int st_t_min ; /* T_Min */ + u_int st_sba ; /* synchr. bandwidth alloc */ + u_int st_frame_ct ; /* frame counter */ + u_int st_error_ct ; /* error counter */ + u_int st_lost_ct ; /* lost frames counter */ } ; /* @@ -305,8 +305,8 @@ struct smt_p_lem { u_char lem_cutoff ; /* 0x4 .. 0xf, default 0x7 */ u_char lem_alarm ; /* 0x4 .. 0xf, default 0x8 */ u_char lem_estimate ; /* 0x0 .. 0xff */ - u_long lem_reject_ct ; /* 0x00000000 .. 0xffffffff */ - u_long lem_ct ; /* 0x00000000 .. 0xffffffff */ + u_int lem_reject_ct ; /* 0x00000000 .. 0xffffffff */ + u_int lem_ct ; /* 0x00000000 .. 0xffffffff */ } ; /* @@ -319,8 +319,8 @@ struct smt_p_mac_counter { struct smt_para para ; /* generic parameter header */ u_short mc_mib_index ; /* MIB index */ u_short mc_index ; /* mac index */ - u_long mc_receive_ct ; /* receive counter */ - u_long mc_transmit_ct ; /* transmit counter */ + u_int mc_receive_ct ; /* receive counter */ + u_int mc_transmit_ct ; /* transmit counter */ } ; /* @@ -333,7 +333,7 @@ struct smt_p_mac_fnc { struct smt_para para ; /* generic parameter header */ u_short nc_mib_index ; /* MIB index */ u_short nc_index ; /* mac index */ - u_long nc_counter ; /* not copied counter */ + u_int nc_counter ; /* not copied counter */ } ; @@ -347,7 +347,7 @@ struct smt_p_priority { struct smt_para para ; /* generic parameter header */ u_short pr_mib_index ; /* MIB index */ u_short pr_index ; /* mac index */ - u_long pr_priority[7] ; /* priority values */ + u_int pr_priority[7] ; /* priority values */ } ; /* @@ -360,7 +360,7 @@ struct smt_p_eb { struct smt_para para ; /* generic parameter header */ u_short eb_mib_index ; /* MIB index */ u_short eb_index ; /* phy index */ - u_long eb_error_ct ; /* # of eb overflows */ + u_int eb_error_ct ; /* # of eb overflows */ } ; /* @@ -406,7 +406,7 @@ struct smt_p_echo { struct smt_p_reason { struct smt_para para ; /* generic parameter header */ - u_long rdf_reason ; /* CLASS/VERSION */ + u_int rdf_reason ; /* CLASS/VERSION */ } ; #define SMT_RDF_CLASS 0x00000001 /* class not supported */ #define SMT_RDF_VERSION 0x00000002 /* version not supported */ @@ -428,7 +428,7 @@ struct smt_p_reason { struct smt_p_refused { struct smt_para para ; /* generic parameter header */ - u_long ref_fc ; /* 3 bytes 0 + FC */ + u_int ref_fc ; /* 3 bytes 0 + FC */ struct smt_header ref_header ; /* refused header */ } ; @@ -454,7 +454,7 @@ struct smt_p_version { struct smt_p_0015 { struct smt_para para ; /* generic parameter header */ - u_long res_type ; /* recsource type */ + u_int res_type ; /* recsource type */ } ; #define SYNC_BW 0x00000001L /* Synchronous Bandwidth */ @@ -466,7 +466,7 @@ struct smt_p_0015 { struct smt_p_0016 { struct smt_para para ; /* generic parameter header */ - u_long sba_cmd ; /* command for the SBA */ + u_int sba_cmd ; /* command for the SBA */ } ; #define REQUEST_ALLOCATION 0x1 /* req allocation of sync bandwidth */ @@ -482,7 +482,7 @@ struct smt_p_0016 { struct smt_p_0017 { struct smt_para para ; /* generic parameter header */ - long sba_pl_req ; /* total sync bandwidth measured in */ + int sba_pl_req ; /* total sync bandwidth measured in */ } ; /* bytes per 125 us */ /* @@ -492,7 +492,7 @@ struct smt_p_0017 { struct smt_p_0018 { struct smt_para para ; /* generic parameter header */ - long sba_ov_req ; /* total sync bandwidth req for overhead*/ + int sba_ov_req ; /* total sync bandwidth req for overhead*/ } ; /* measuered in bytes per T_Neg */ /* @@ -513,7 +513,7 @@ struct smt_p_0019 { struct smt_p_001a { struct smt_para para ; /* generic parameter header */ - u_long category ; /* Allocator defined classification */ + u_int category ; /* Allocator defined classification */ } ; /* @@ -523,7 +523,7 @@ struct smt_p_001a { struct smt_p_001b { struct smt_para para ; /* generic parameter header */ - u_long max_t_neg ; /* longest T_NEG for the sync service*/ + u_int max_t_neg ; /* longest T_NEG for the sync service*/ } ; /* @@ -533,7 +533,7 @@ struct smt_p_001b { struct smt_p_001c { struct smt_para para ; /* generic parameter header */ - u_long min_seg_siz ; /* smallest number of bytes per frame*/ + u_int min_seg_siz ; /* smallest number of bytes per frame*/ } ; /* @@ -543,7 +543,7 @@ struct smt_p_001c { struct smt_p_001d { struct smt_para para ; /* generic parameter header */ - u_long allocatable ; /* total sync bw availabel for alloc */ + u_int allocatable ; /* total sync bw availabel for alloc */ } ; /* @@ -575,8 +575,8 @@ struct smt_p_fsc { */ #define SWAP_SMT_P1048 "ll" struct smt_p_1048 { - u_long p1048_flag ; - u_long p1048_cf_state ; + u_int p1048_flag ; + u_int p1048_cf_state ; } ; /* @@ -586,7 +586,7 @@ struct smt_p_1048 { */ #define SWAP_SMT_P208C "4lss66" struct smt_p_208c { - u_long p208c_flag ; + u_int p208c_flag ; u_short p208c_pad ; u_short p208c_dupcondition ; struct fddi_addr p208c_fddilong ; @@ -595,26 +595,26 @@ struct smt_p_208c { #define SWAP_SMT_P208D "4lllll" struct smt_p_208d { - u_long p208d_flag ; - u_long p208d_frame_ct ; - u_long p208d_error_ct ; - u_long p208d_lost_ct ; - u_long p208d_ratio ; + u_int p208d_flag ; + u_int p208d_frame_ct ; + u_int p208d_error_ct ; + u_int p208d_lost_ct ; + u_int p208d_ratio ; } ; #define SWAP_SMT_P208E "4llll" struct smt_p_208e { - u_long p208e_flag ; - u_long p208e_not_copied ; - u_long p208e_copied ; - u_long p208e_not_copied_ratio ; + u_int p208e_flag ; + u_int p208e_not_copied ; + u_int p208e_copied ; + u_int p208e_not_copied_ratio ; } ; #define SWAP_SMT_P208F "4ll6666s6" struct smt_p_208f { - u_long p208f_multiple ; - u_long p208f_nacondition ; + u_int p208f_multiple ; + u_int p208f_nacondition ; struct fddi_addr p208f_old_una ; struct fddi_addr p208f_new_una ; struct fddi_addr p208f_old_dna ; @@ -626,10 +626,10 @@ struct smt_p_208f { #define SWAP_SMT_P2090 "4lssl" struct smt_p_2090 { - u_long p2090_multiple ; + u_int p2090_multiple ; u_short p2090_availablepaths ; u_short p2090_currentpath ; - u_long p2090_requestedpaths ; + u_int p2090_requestedpaths ; } ; /* @@ -649,7 +649,7 @@ struct smt_p_2090 { struct smt_p_320b { struct smt_para para ; /* generic parameter header */ - u_long mib_index ; + u_int mib_index ; u_short path_pad ; u_short path_index ; } ; @@ -658,33 +658,33 @@ struct smt_p_320b { struct smt_p_320f { struct smt_para para ; /* generic parameter header */ - u_long mib_index ; - u_long mib_payload ; + u_int mib_index ; + u_int mib_payload ; } ; #define SWAP_SMT_P3210 "4l" struct smt_p_3210 { struct smt_para para ; /* generic parameter header */ - u_long mib_index ; - u_long mib_overhead ; + u_int mib_index ; + u_int mib_overhead ; } ; #define SWAP_SMT_P4050 "4l1111ll" struct smt_p_4050 { - u_long p4050_flag ; + u_int p4050_flag ; u_char p4050_pad ; u_char p4050_cutoff ; u_char p4050_alarm ; u_char p4050_estimate ; - u_long p4050_reject_ct ; - u_long p4050_ct ; + u_int p4050_reject_ct ; + u_int p4050_ct ; } ; #define SWAP_SMT_P4051 "4lssss" struct smt_p_4051 { - u_long p4051_multiple ; + u_int p4051_multiple ; u_short p4051_porttype ; u_short p4051_connectstate ; u_short p4051_pc_neighbor ; @@ -693,17 +693,17 @@ struct smt_p_4051 { #define SWAP_SMT_P4052 "4ll" struct smt_p_4052 { - u_long p4052_flag ; - u_long p4052_eberrorcount ; + u_int p4052_flag ; + u_int p4052_eberrorcount ; } ; #define SWAP_SMT_P4053 "4lsslss" struct smt_p_4053 { - u_long p4053_multiple ; + u_int p4053_multiple ; u_short p4053_availablepaths ; u_short p4053_currentpath ; - u_long p4053_requestedpaths ; + u_int p4053_requestedpaths ; u_short p4053_mytype ; u_short p4053_neighbortype ; } ; @@ -714,7 +714,7 @@ struct smt_p_4053 { struct smt_p_setcount { struct smt_para para ; /* generic parameter header */ - u_long count ; + u_int count ; u_char timestamp[8] ; } ; diff --git a/drivers/net/skfp/h/targetos.h b/drivers/net/skfp/h/targetos.h index dd88fb35e..7c6c1bd85 100644 --- a/drivers/net/skfp/h/targetos.h +++ b/drivers/net/skfp/h/targetos.h @@ -93,7 +93,7 @@ #define u8 unsigned char #define u16 unsigned short -#define u32 unsigned long +#define u32 unsigned int #define MAX_TX_QUEUE_LEN 20 // number of packets queued by driver #define MAX_FRAME_SIZE 4550 @@ -127,11 +127,12 @@ struct s_smt_os { u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */ struct pci_dev pdev; /* PCI device structure */ - u32 base_addr; + unsigned long base_addr; unsigned char factory_mac_addr[8]; ulong SharedMemSize; ulong SharedMemHeap; void* SharedMemAddr; + dma_addr_t SharedMemDMA; ulong QueueSkb; struct sk_buff_head SendSkbQueue; @@ -144,8 +145,10 @@ struct s_smt_os { // receive into this local buffer if no skb available // data will be not valid, because multiple RxDs can - // point here at the same time - unsigned char LocalRxBuffer[MAX_FRAME_SIZE]; + // point here at the same time, it must be at least + // MAX_FRAME_SIZE bytes in size + unsigned char *LocalRxBuffer; + dma_addr_t LocalRxBufferDMA; // Version (required by SMT module). u_long smc_version ; diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c index 366b3b890..ece539646 100644 --- a/drivers/net/skfp/hwmtm.c +++ b/drivers/net/skfp/hwmtm.c @@ -456,7 +456,7 @@ u_char *mac_addr ; /* canonical address */ /* * make sure that the start pointer is 16 byte aligned */ - i = 16 - ((int)smc->os.hwm.descr_p & 0xf) ; + i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ; if (i != 16) { DB_GEN("i = %d",i,0,3) ; smc->os.hwm.descr_p = (union s_fp_descr volatile *) @@ -1087,9 +1087,8 @@ struct s_smc *smc ; DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; rbctrl = CR_READ(r->rxd_rbctrl) ; -#ifdef AIX rbctrl = AIX_REVERSE(rbctrl) ; -#endif + if (rbctrl & BMU_OWN) { NDD_TRACE("RHxE",r,rfsw,rbctrl) ; DB_RX("End of RxDs",0,0,4) ; @@ -1425,26 +1424,19 @@ int len ; int frame_status ; { struct s_smt_fp_rxd volatile *r ; -#ifdef AIX - u_long rbctrl ; -#endif + u_int rbctrl ; NDD_TRACE("RHfB",virt,len,frame_status) ; DB_RX("hwm_rx_frag: len = %d, frame_status = %x\n",len,frame_status,2) ; r = smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put ; r->rxd_virt = virt ; r->rxd_rbadr = AIX_REVERSE(phys) ; -#ifndef AIX - r->rxd_rbctrl = (((u_long)frame_status & (FIRST_FRAG|LAST_FRAG))<<26) | - (((u_long) frame_status & FIRST_FRAG) << 21) | - BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len ; -#else rbctrl = AIX_REVERSE( (((u_long)frame_status & (FIRST_FRAG|LAST_FRAG))<<26) | (((u_long) frame_status & FIRST_FRAG) << 21) | BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len) ; r->rxd_rbctrl = rbctrl ; -#endif + DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ; outpd(ADDR(B0_R1_CSR),CSR_START) ; smc->hw.fp.rx_q[QUEUE_R1].rx_free-- ; @@ -1687,9 +1679,7 @@ int frame_status ; { struct s_smt_fp_txd volatile *t ; struct s_smt_tx_queue *queue ; -#ifdef AIX - u_long tbctrl ; -#endif + u_int tbctrl ; queue = smc->os.hwm.tx_p ; @@ -1708,19 +1698,15 @@ int frame_status ; t->txd_virt = virt ; t->txd_txdscr = AIX_REVERSE(smc->os.hwm.tx_descr) ; t->txd_tbadr = AIX_REVERSE(phys) ; -#ifndef AIX - t->txd_tbctrl = (((u_long)frame_status & - (FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) | - BMU_OWN|BMU_CHECK |len ; - DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; - outpd(queue->tx_bmu_ctl,CSR_START) ; - -#else /* ifndef AIX */ tbctrl = AIX_REVERSE((((u_long)frame_status & (FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) | BMU_OWN|BMU_CHECK |len) ; t->txd_tbctrl = tbctrl ; +#ifndef AIX + DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; + outpd(queue->tx_bmu_ctl,CSR_START) ; +#else /* ifndef AIX */ DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; if (frame_status & QUEUE_A0) { outpd(ADDR(B0_XA_CSR),CSR_START) ; @@ -1888,9 +1874,7 @@ int fc; struct s_smt_tx_queue *queue ; struct s_smt_fp_txd volatile *t ; u_long phys ; -#ifdef AIX - u_long tbctrl ; -#endif + u_int tbctrl ; NDD_TRACE("THSB",mb,fc,0) ; DB_TX("smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ; @@ -1908,7 +1892,7 @@ int fc; frag_count = 0 ; len = mb->sm_len ; while (len) { - n = SMT_PAGESIZE - ((int)data & (SMT_PAGESIZE-1)) ; + n = SMT_PAGESIZE - ((long)data & (SMT_PAGESIZE-1)) ; if (n >= len) { n = len ; } @@ -1964,17 +1948,14 @@ int fc; phys = dma_master(smc, (void far *)virt[i], frag_len[i], DMA_RD|SMT_BUF) ; t->txd_tbadr = AIX_REVERSE(phys) ; -#ifndef AIX - t->txd_tbctrl = (((u_long) frame_status & - (FIRST_FRAG|LAST_FRAG)) << 26) | - BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i] ; - DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; - outpd(queue->tx_bmu_ctl,CSR_START) ; -#else tbctrl = AIX_REVERSE((((u_long) frame_status & (FIRST_FRAG|LAST_FRAG)) << 26) | BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i]) ; t->txd_tbctrl = tbctrl ; +#ifndef AIX + DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; + outpd(queue->tx_bmu_ctl,CSR_START) ; +#else DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ; outpd(ADDR(B0_XA_CSR),CSR_START) ; #endif @@ -2039,9 +2020,8 @@ struct s_smc *smc ; DRV_BUF_FLUSH(t1,DDI_DMA_SYNC_FORCPU) ; DB_TX("check OWN/EOF bit of TxD 0x%x",t1,0,5) ; tbctrl = CR_READ(t1->txd_tbctrl) ; -#ifdef AIX tbctrl = AIX_REVERSE(tbctrl) ; -#endif + if (tbctrl & BMU_OWN || !queue->tx_used){ DB_TX("End of TxDs queue %d",i,0,4) ; goto free_next_queue ; /* next queue */ diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 1bbd5f068..5b5ffc9f9 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -19,6 +19,9 @@ * Maintainers: * CG Christoph Goos (cgoos@syskonnect.de) * + * Contributors: + * DM David S. Miller + * * Address all question to: * linux@syskonnect.de * @@ -52,20 +55,20 @@ * 26-Oct-99 CG Fixed compilation error on 2.2.13 * 12-Nov-99 CG Source code release * 22-Nov-99 CG Included in kernel source. + * 07-May-00 DM 64 bit fixes, new dma interface * * Compilation options (-Dxxx): * DRIVERDEBUG print lots of messages to log file * DUMPPACKETS print received/transmitted packets to logfile * - * Limitations: - * I changed the driver to support memory mapped I/O, so it - * might run on non-x86 architectures (not tested). - * But the hardware module does not yet support 64 bit OS'es. + * Tested cpu architectures: + * - i386 + * - sparc64 */ /* Version information string - should be updated prior to */ /* each new release!!! */ -#define VERSION "2.05" +#define VERSION "2.06" static const char *boot_msg = "SysKonnect FDDI PCI Adapter driver v" VERSION " for\n" @@ -666,18 +669,28 @@ static int skfp_driver_init(struct net_device *dev) spin_lock_init(&bp->DriverLock); + // Allocate invalid frame + bp->LocalRxBuffer = pci_alloc_consistent(&bp->pdev, MAX_FRAME_SIZE, &bp->LocalRxBufferDMA); + if (!bp->LocalRxBuffer) { + printk("could not allocate mem for "); + printk("LocalRxBuffer: %d byte\n", MAX_FRAME_SIZE); + goto fail; + } + // Determine the required size of the 'shared' memory area. bp->SharedMemSize = mac_drv_check_space(); PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize); if (bp->SharedMemSize > 0) { bp->SharedMemSize += 16; // for descriptor alignment - bp->SharedMemAddr = kmalloc(bp->SharedMemSize, GFP_KERNEL); + bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev, + bp->SharedMemSize, + &bp->SharedMemDMA); if (!bp->SharedMemSize) { printk("could not allocate mem for "); printk("hardware module: %ld byte\n", bp->SharedMemSize); - return (-1); + goto fail; } bp->SharedMemHeap = 0; // Nothing used yet. @@ -693,7 +706,7 @@ static int skfp_driver_init(struct net_device *dev) PRINTK(KERN_INFO "mac_drv_init()..\n"); if (mac_drv_init(smc) != 0) { PRINTK(KERN_INFO "mac_drv_init() failed.\n"); - return (-1); + goto fail; } read_address(smc, NULL); PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n", @@ -708,6 +721,21 @@ static int skfp_driver_init(struct net_device *dev) smt_reset_defaults(smc, 0); return (0); + +fail: + if (bp->SharedMemAddr) { + pci_free_consistent(&bp->pdev, + bp->SharedMemSize, + bp->SharedMemAddr, + bp->SharedMemDMA); + bp->SharedMemAddr = NULL; + } + if (bp->LocalRxBuffer) { + pci_free_consistent(&bp->pdev, MAX_FRAME_SIZE, + bp->LocalRxBuffer, bp->LocalRxBufferDMA); + bp->LocalRxBuffer = NULL; + } + return (-1); } // skfp_driver_init @@ -1282,7 +1310,7 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) * is contained in a single physically contiguous buffer * in which the virtual address of the start of packet * (skb->data) can be converted to a physical address - * by using virt_to_bus(). + * by using pci_map_single(). * * We have an internal queue for packets we can not send * immediately. Packets in this queue can be given to the @@ -1378,6 +1406,7 @@ static void send_queued_packets(struct s_smc *smc) unsigned char fc; int queue; struct s_smt_fp_txd *txd; // Current TxD. + dma_addr_t dma_address; unsigned long Flags; int frame_status; // HWM tx frame status. @@ -1442,13 +1471,18 @@ static void send_queued_packets(struct s_smc *smc) txd = (struct s_smt_fp_txd *) HWM_GET_CURR_TXD(smc, queue); + dma_address = pci_map_single(&bp->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); if (frame_status & LAN_TX) { - txd->txd_os.skb = skb; // save skb + txd->txd_os.skb = skb; // save skb + txd->txd_os.dma_addr = dma_address; // save dma mapping } - hwm_tx_frag(smc, skb->data, virt_to_bus(skb->data), skb->len, + hwm_tx_frag(smc, skb->data, dma_address, skb->len, frame_status | FIRST_FRAG | LAST_FRAG | EN_IRQ_EOF); if (!(frame_status & LAN_TX)) { // local only frame + pci_unmap_single(&bp->pdev, dma_address, + skb->len, PCI_DMA_TODEVICE); dev_kfree_skb_irq(skb); } spin_unlock_irqrestore(&bp->DriverLock, Flags); @@ -1571,7 +1605,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) { void *virt; - PRINTK(KERN_INFO "mac_drv_get_space\n"); + PRINTK(KERN_INFO "mac_drv_get_space (%d bytes), ", size); virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap); if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) { @@ -1581,8 +1615,10 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) smc->os.SharedMemHeap += size; // Move heap pointer. PRINTK(KERN_INFO "mac_drv_get_space end\n"); - PRINTK(KERN_INFO "virt addr: %08lx\n", (ulong) virt); - PRINTK(KERN_INFO "bus addr: %08lx\n", (ulong) virt_to_bus(virt)); + PRINTK(KERN_INFO "virt addr: %lx\n", (ulong) virt); + PRINTK(KERN_INFO "bus addr: %lx\n", (ulong) + (smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr))); return (virt); } // mac_drv_get_space @@ -1616,7 +1652,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) virt = mac_drv_get_space(smc, size); - size = (u_int) ((0 - (unsigned int) virt) & 15); + size = (u_int) ((0 - (unsigned long) virt) & 15UL); PRINTK("Allocate %u bytes alignment gap ", size); PRINTK("for descriptor memory.\n"); @@ -1644,7 +1680,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) ************************/ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) { - return virt_to_bus(virt); + return (smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr)); } // mac_drv_virt2phys @@ -1657,7 +1694,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) * for the DMA transfer, it should do it in this function. * * The hardware module calls this dma_master if it wants to send an SMT - * frame. + * frame. This means that the virt address passed in here is part of + * the 'shared' memory area. * Args * smc - A pointer to the SMT context struct. * @@ -1677,7 +1715,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) ************************/ u_long dma_master(struct s_smc * smc, void *virt, int len, int flag) { - return (virt_to_bus(virt)); + return (smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr)); } // dma_master @@ -1704,7 +1743,31 @@ u_long dma_master(struct s_smc * smc, void *virt, int len, int flag) ************************/ void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr, int flag) { - return; + /* For TX buffers, there are two cases. If it is an SMT transmit + * buffer, there is nothing to do since we use consistent memory + * for the 'shared' memory area. The other case is for normal + * transmit packets given to us by the networking stack, and in + * that case we cleanup the PCI DMA mapping in mac_drv_tx_complete + * below. + * + * For RX buffers, we have to unmap dynamic PCI DMA mappings here + * because the hardware module is about to potentially look at + * the contents of the buffer. If we did not call the PCI DMA + * unmap first, the hardware module could read inconsistent data. + */ + if (flag & DMA_WR) { + skfddi_priv *bp = (skfddi_priv *) & smc->os; + volatile struct s_smt_fp_rxd *r = &descr->r; + + /* If SKB is NULL, we used the local buffer. */ + if (r->rxd_os.skb && r->rxd_os.dma_addr) { + int MaxFrameSize = bp->MaxFrameSize; + + pci_unmap_single(&bp->pdev, r->rxd_os.dma_addr, + MaxFrameSize, PCI_DMA_FROMDEVICE); + r->rxd_os.dma_addr = 0; + } + } } // dma_complete @@ -1735,6 +1798,11 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) } txd->txd_os.skb = NULL; + // release the DMA mapping + pci_unmap_single(&smc->os.pdev, txd->txd_os.dma_addr, + skb->len, PCI_DMA_TODEVICE); + txd->txd_os.dma_addr = 0; + smc->os.MacStat.tx_packets++; // Count transmitted packets. smc->os.MacStat.tx_bytes+=skb->len; // Count bytes @@ -1823,6 +1891,8 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, } virt = skb->data; + // The DMA mapping was released in dma_complete above. + dump_data(skb->data, len); /* @@ -1923,7 +1993,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, struct sk_buff *skb; int MaxFrameSize; unsigned char *v_addr; - unsigned long b_addr; + dma_addr_t b_addr; if (frag_count != 1) // This is not allowed to happen. @@ -1939,25 +2009,34 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, if (skb == NULL) { // this should not happen PRINTK("Requeue with no skb in rxd!\n"); - skb = alloc_skb(MaxFrameSize, GFP_ATOMIC); + skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC); if (skb) { // we got a skb rxd->rxd_os.skb = skb; + skb_reserve(skb, 3); skb_put(skb, MaxFrameSize); v_addr = skb->data; - b_addr = virt_to_bus(v_addr); + b_addr = pci_map_single(&smc->os.pdev, + v_addr, + MaxFrameSize, + PCI_DMA_FROMDEVICE); + rxd->rxd_os.dma_addr = b_addr; } else { // no skb available, use local buffer PRINTK("Queueing invalid buffer!\n"); rxd->rxd_os.skb = NULL; v_addr = smc->os.LocalRxBuffer; - b_addr = virt_to_bus(v_addr); + b_addr = smc->os.LocalRxBufferDMA; } } else { // we use skb from old rxd rxd->rxd_os.skb = skb; v_addr = skb->data; - b_addr = virt_to_bus(v_addr); + b_addr = pci_map_single(&smc->os.pdev, + v_addr, + MaxFrameSize, + PCI_DMA_FROMDEVICE); + rxd->rxd_os.dma_addr = b_addr; } hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize, FIRST_FRAG | LAST_FRAG); @@ -2002,12 +2081,17 @@ void mac_drv_fill_rxd(struct s_smc *smc) PRINTK(KERN_INFO ".\n"); rxd = HWM_GET_CURR_RXD(smc); - skb = alloc_skb(MaxFrameSize, GFP_ATOMIC); + skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC); if (skb) { // we got a skb + skb_reserve(skb, 3); skb_put(skb, MaxFrameSize); v_addr = skb->data; - b_addr = virt_to_bus(v_addr); + b_addr = pci_map_single(&smc->os.pdev, + v_addr, + MaxFrameSize, + PCI_DMA_FROMDEVICE); + rxd->rxd_os.dma_addr = b_addr; } else { // no skb available, use local buffer // System has run out of buffer memory, but we want to @@ -2016,7 +2100,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) // so data in it must be considered invalid. PRINTK("Queueing invalid buffer!\n"); v_addr = smc->os.LocalRxBuffer; - b_addr = virt_to_bus(v_addr); + b_addr = smc->os.LocalRxBufferDMA; } rxd->rxd_os.skb = skb; @@ -2060,6 +2144,12 @@ void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, for (; frag_count > 0; frag_count--) { skb = rxd->rxd_os.skb; if (skb != NULL) { + skfddi_priv *bp = (skfddi_priv *) & smc->os; + int MaxFrameSize = bp->MaxFrameSize; + + pci_unmap_single(&bp->pdev, rxd->rxd_os.dma_addr, + MaxFrameSize, PCI_DMA_FROMDEVICE); + dev_kfree_skb(skb); rxd->rxd_os.skb = NULL; } @@ -2111,11 +2201,12 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc, len, la_len, (unsigned long) look_ahead); return (0); } - skb = alloc_skb(len, GFP_ATOMIC); + skb = alloc_skb(len + 3, GFP_ATOMIC); if (!skb) { PRINTK("fddi: Local SMT: skb memory exhausted.\n"); return (0); } + skb_reserve(skb, 3); skb_put(skb, len); memcpy(skb->data, look_ahead, len); @@ -2162,7 +2253,40 @@ void smt_timer_poll(struct s_smc *smc) ************************/ void ring_status_indication(struct s_smc *smc, u_long status) { - PRINTK("ring_status_indication(%08lXh)\n", (unsigned long) status); + PRINTK("ring_status_indication( "); + if (status & RS_RES15) + PRINTK("RS_RES15 "); + if (status & RS_HARDERROR) + PRINTK("RS_HARDERROR "); + if (status & RS_SOFTERROR) + PRINTK("RS_SOFTERROR "); + if (status & RS_BEACON) + PRINTK("RS_BEACON "); + if (status & RS_PATHTEST) + PRINTK("RS_PATHTEST "); + if (status & RS_SELFTEST) + PRINTK("RS_SELFTEST "); + if (status & RS_RES9) + PRINTK("RS_RES9 "); + if (status & RS_DISCONNECT) + PRINTK("RS_DISCONNECT "); + if (status & RS_RES7) + PRINTK("RS_RES7 "); + if (status & RS_DUPADDR) + PRINTK("RS_DUPADDR "); + if (status & RS_NORINGOP) + PRINTK("RS_NORINGOP "); + if (status & RS_VERSION) + PRINTK("RS_VERSION "); + if (status & RS_STUCKBYPASSS) + PRINTK("RS_STUCKBYPASSS "); + if (status & RS_EVENT) + PRINTK("RS_EVENT "); + if (status & RS_RINGOPCHANGE) + PRINTK("RS_RINGOPCHANGE "); + if (status & RS_RES0) + PRINTK("RS_RES0 "); + PRINTK("]\n"); } // ring_status_indication @@ -2261,9 +2385,18 @@ void cfm_state_change(struct s_smc *smc, int c_state) case SC7_WRAP_S: s = "SC7_WRAP_S"; break; - default: - s = "unknown"; + case SC9_C_WRAP_A: + s = "SC9_C_WRAP_A"; + break; + case SC10_C_WRAP_B: + s = "SC10_C_WRAP_B"; + break; + case SC11_C_WRAP_S: + s = "SC11_C_WRAP_S"; break; + default: + PRINTK(KERN_INFO "cfm_state_change: unknown %d\n", c_state); + return; } PRINTK(KERN_INFO "cfm_state_change: %s\n", s); #endif // DRIVERDEBUG @@ -2478,7 +2611,18 @@ static struct net_device *unlink_modules(struct net_device *p) next = lp->os.next_module; if (lp->os.SharedMemAddr) { - kfree(lp->os.SharedMemAddr); + pci_free_consistent(&lp->os.pdev, + lp->os.SharedMemSize, + lp->os.SharedMemAddr, + lp->os.SharedMemDMA); + lp->os.SharedMemAddr = NULL; + } + if (lp->os.LocalRxBuffer) { + pci_free_consistent(&lp->os.pdev, + MAX_FRAME_SIZE, + lp->os.LocalRxBuffer, + lp->os.LocalRxBufferDMA); + lp->os.LocalRxBuffer = NULL; } release_region(p->base_addr, (lp->os.bus_type == SK_BUS_TYPE_PCI ? FP_IO_LEN : 0)); |