summaryrefslogtreecommitdiffstats
path: root/drivers/net/skfp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/skfp')
-rw-r--r--drivers/net/skfp/fplustm.c28
-rw-r--r--drivers/net/skfp/h/fplustm.h24
-rw-r--r--drivers/net/skfp/h/osdef1st.h17
-rw-r--r--drivers/net/skfp/h/smt.h114
-rw-r--r--drivers/net/skfp/h/targetos.h11
-rw-r--r--drivers/net/skfp/hwmtm.c52
-rw-r--r--drivers/net/skfp/skfddi.c208
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));