Changeset 5


Ignore:
Timestamp:
Feb 19, 2008, 5:03:59 PM (16 years ago)
Author:
wade
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • gpxe_study/kernel_2.6.20_src/sis900.c

    r4 r5  
    974974    /* Equalizer workaround Rule */
    975975    sis630_set_eq(net_dev, sis_priv->chipset_rev);
    976     ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED,
    977             net_dev->name, net_dev);
     976    ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED, net_dev->name, net_dev);
    978977    if (ret)
    979978        return ret;
     979
    980980
    981981    sis900_init_rxfilter(net_dev);
     
    10941094{
    10951095    u32 rfcrSave;
    1096   struct sis900_private *sis_priv = net_dev->priv;
    1097   long ioaddr = net_dev->base_addr;
    1098   u32 i;
     1096    struct sis900_private *sis_priv = net_dev->priv;
     1097    long ioaddr = net_dev->base_addr;
     1098    u32 i;
    10991099    rfcrSave = inl(rfcr + ioaddr);
    11001100
     
    11301130sis900_init_tx_ring(struct net_device *net_dev)
    11311131{
    1132   struct sis900_private *sis_priv = net_dev->priv;
    1133   long ioaddr = net_dev->base_addr;
    1134   int i;
    1135 
    1136   sis_priv->tx_full = 0;
    1137   sis_priv->dirty_tx = sis_priv->cur_tx = 0;
    1138 
    1139   for (i = 0; i < NUM_TX_DESC; i++) {
    1140     sis_priv->tx_skbuff[i] = NULL;
    1141 
    1142     sis_priv->tx_ring[i].link = sis_priv->tx_ring_dma +
    1143       ((i+1)%NUM_TX_DESC)*sizeof(BufferDesc);
    1144     sis_priv->tx_ring[i].cmdsts = 0;
     1132    struct sis900_private *sis_priv = net_dev->priv;
     1133    long ioaddr = net_dev->base_addr;
     1134    int i;
     1135    sis_priv->tx_full = 0;
     1136    sis_priv->dirty_tx = sis_priv->cur_tx = 0;
     1137    for (i = 0; i < NUM_TX_DESC; i++) {
     1138        sis_priv->tx_skbuff[i] = NULL;
     1139  sis_priv->tx_ring[i].link = sis_priv->tx_ring_dma +
     1140    ((i+1)%NUM_TX_DESC)*sizeof(BufferDesc);
     1141  sis_priv->tx_ring[i].cmdsts = 0;
    11451142    sis_priv->tx_ring[i].bufptr = 0;
    1146   }
    1147 
    1148   /* load Transmit Descriptor Register */
    1149   outl(sis_priv->tx_ring_dma, ioaddr + txdp);
    1150   if (netif_msg_hw(sis_priv))
    1151     printk(KERN_DEBUG "%s: TX descriptor register loaded with: %8.8x\n",
    1152            net_dev->name, inl(ioaddr + txdp));
     1143    }
     1144
     1145    /* load Transmit Descriptor Register */
     1146    outl(sis_priv->tx_ring_dma, ioaddr + txdp);
     1147    if (netif_msg_hw(sis_priv))
     1148        printk(KERN_DEBUG "%s: TX descriptor register loaded with: %8.8x\n",
     1149              net_dev->name, inl(ioaddr + txdp));
    11531150}
    11541151
     
    12061203    printk(KERN_DEBUG "%s: RX descriptor register loaded with: %8.8x\n",
    12071204           net_dev->name, inl(ioaddr + rxdp));
     1205}
     1206
     1207/**
     1208 *  set_rx_mode - Set SiS900 receive mode
     1209 *  @net_dev: the net device to be set
     1210 *
     1211 *  Set SiS900 receive mode for promiscuous, multicast, or broadcast mode.
     1212 *  And set the appropriate multicast filter.
     1213 *  Multicast hash table changes from 128 to 256 bits for 635M/B & 900B0.
     1214 */
     1215
     1216static void set_rx_mode(struct net_device *net_dev)
     1217{
     1218    int i, table_entries;
     1219    u32 rx_mode;
     1220    long ioaddr = net_dev->base_addr;
     1221    struct sis900_private * sis_priv = net_dev->priv;
     1222    u16 mc_filter[16] = {0};  /* 256/128 bits multicast hash table */
     1223    /* 635 Hash Table entries = 256(2^16) */
     1224     
     1225    if((sis_priv->chipset_rev >= SIS635A_900_REV) || (sis_priv->chipset_rev == SIS900B_900_REV))
     1226  table_entries = 16;
     1227    else
     1228  table_entries = 8;
     1229    if (net_dev->flags & IFF_PROMISC) {
     1230    /* Accept any kinds of packets */
     1231        rx_mode = RFPromiscuous;
     1232        for (i = 0; i < table_entries; i++)
     1233      mc_filter[i] = 0xffff;
     1234    } else if ((net_dev->mc_count > multicast_filter_limit) || (net_dev->flags & IFF_ALLMULTI)) {
     1235
     1236    /* too many multicast addresses or accept all multicast packet */
     1237    rx_mode = RFAAB | RFAAM;
     1238    for (i = 0; i < table_entries; i++)
     1239    mc_filter[i] = 0xffff;
     1240         
     1241    } else {
     1242  /* Accept Broadcast packet, destination address matchs our
     1243   * MAC address, use Receive Filter to reject unwanted MCAST
     1244   * packets */
     1245  struct dev_mc_list *mclist;
     1246  rx_mode = RFAAB;
     1247  for (i = 0, mclist = net_dev->mc_list;
     1248    mclist && i < net_dev->mc_count;
     1249    i++, mclist = mclist->next) {
     1250    unsigned int bit_nr = sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev);
     1251    mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
     1252        }
     1253    }
     1254    /* update Multicast Hash Table in Receive Filter */
     1255    for (i = 0; i < table_entries; i++) {
     1256        /* why plus 0x04 ??, That makes the correct value for hash table. */
     1257        outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
     1258        outl(mc_filter[i], ioaddr + rfdr);
     1259    }
     1260
     1261    outl(RFEN | rx_mode, ioaddr + rfcr);
     1262
     1263    /* sis900 is capable of looping back packets at MAC level for
     1264     * debugging purpose */
     1265    if (net_dev->flags & IFF_LOOPBACK) {
     1266  u32 cr_saved;
     1267  /* We must disable Tx/Rx before setting loopback mode */
     1268  cr_saved = inl(ioaddr + cr);
     1269  outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);
     1270  /* enable loopback */
     1271  outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);
     1272  outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);
     1273  /* restore cr */
     1274  outl(cr_saved, ioaddr + cr);
     1275    }
     1276
     1277    return;
     1278}
     1279
     1280
     1281/* Function: sis900_check_mode
     1282 *
     1283 * - check the media mode for sis900
     1284 *  @net_dev: the net device to be checked
     1285 *  @mii_phy: the mii phy
     1286 *
     1287 *  Older driver gets the media mode from mii status output
     1288 *  register. Now we set our media capability and auto-negotiate
     1289 *  to get the upper bound of speed and duplex between two ends.
     1290 *  If the types of mii phy is HOME, it doesn't need to auto-negotiate
     1291 *  and autong_complete should be set to 1.
     1292 * Returns:   void.
     1293 */
     1294
     1295static void
     1296sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)
     1297{
     1298    int speed, duplex;
     1299    struct sis900_private *sis_priv = net_dev->priv;
     1300    long ioaddr = net_dev->base_addr;
     1301
     1302  if (mii_phy->phy_types == LAN) {
     1303    outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg);
     1304    sis900_set_capability(net_dev , mii_phy);
     1305    sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
     1306  } else {
     1307    outl(EXD | inl(ioaddr + cfg), ioaddr + cfg);
     1308    speed = HW_SPEED_HOME;
     1309    duplex = FDX_CAPABLE_HALF_SELECTED;
     1310    sis900_set_mode(ioaddr, speed, duplex);
     1311    sis_priv->autong_complete = 1;
     1312  }
    12081313}
    12091314
     
    12991404}
    13001405
     1406
    13011407/**
    13021408 *  sis900_timer - sis900 timer routine
     
    13661472}
    13671473
    1368 /**
    1369  *  sis900_check_mode - check the media mode for sis900
    1370  *  @net_dev: the net device to be checked
    1371  *  @mii_phy: the mii phy
    1372  *
    1373  *  Older driver gets the media mode from mii status output
    1374  *  register. Now we set our media capability and auto-negotiate
    1375  *  to get the upper bound of speed and duplex between two ends.
    1376  *  If the types of mii phy is HOME, it doesn't need to auto-negotiate
    1377  *  and autong_complete should be set to 1.
    1378  */
    1379 
    1380 static void sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)
    1381 {
    1382   struct sis900_private *sis_priv = net_dev->priv;
    1383   long ioaddr = net_dev->base_addr;
    1384   int speed, duplex;
    1385 
    1386   if (mii_phy->phy_types == LAN) {
    1387     outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg);
    1388     sis900_set_capability(net_dev , mii_phy);
    1389     sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
    1390   } else {
    1391     outl(EXD | inl(ioaddr + cfg), ioaddr + cfg);
    1392     speed = HW_SPEED_HOME;
    1393     duplex = FDX_CAPABLE_HALF_SELECTED;
    1394     sis900_set_mode(ioaddr, speed, duplex);
    1395     sis_priv->autong_complete = 1;
    1396   }
    1397 }
    13981474
    13991475/**
     
    23152391}
    23162392
    2317 /**
    2318  *  set_rx_mode - Set SiS900 receive mode
    2319  *  @net_dev: the net device to be set
    2320  *
    2321  *  Set SiS900 receive mode for promiscuous, multicast, or broadcast mode.
    2322  *  And set the appropriate multicast filter.
    2323  *  Multicast hash table changes from 128 to 256 bits for 635M/B & 900B0.
    2324  */
    2325 
    2326 static void set_rx_mode(struct net_device *net_dev)
    2327 {
    2328   long ioaddr = net_dev->base_addr;
    2329   struct sis900_private * sis_priv = net_dev->priv;
    2330   u16 mc_filter[16] = {0};  /* 256/128 bits multicast hash table */
    2331   int i, table_entries;
    2332   u32 rx_mode;
    2333 
    2334   /* 635 Hash Table entries = 256(2^16) */
    2335   if((sis_priv->chipset_rev >= SIS635A_900_REV) ||
    2336       (sis_priv->chipset_rev == SIS900B_900_REV))
    2337     table_entries = 16;
    2338   else
    2339     table_entries = 8;
    2340 
    2341   if (net_dev->flags & IFF_PROMISC) {
    2342     /* Accept any kinds of packets */
    2343     rx_mode = RFPromiscuous;
    2344     for (i = 0; i < table_entries; i++)
    2345       mc_filter[i] = 0xffff;
    2346   } else if ((net_dev->mc_count > multicast_filter_limit) ||
    2347        (net_dev->flags & IFF_ALLMULTI)) {
    2348     /* too many multicast addresses or accept all multicast packet */
    2349     rx_mode = RFAAB | RFAAM;
    2350     for (i = 0; i < table_entries; i++)
    2351       mc_filter[i] = 0xffff;
    2352   } else {
    2353     /* Accept Broadcast packet, destination address matchs our
    2354      * MAC address, use Receive Filter to reject unwanted MCAST
    2355      * packets */
    2356     struct dev_mc_list *mclist;
    2357     rx_mode = RFAAB;
    2358     for (i = 0, mclist = net_dev->mc_list;
    2359       mclist && i < net_dev->mc_count;
    2360       i++, mclist = mclist->next) {
    2361       unsigned int bit_nr =
    2362         sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev);
    2363       mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
    2364     }
    2365   }
    2366 
    2367   /* update Multicast Hash Table in Receive Filter */
    2368   for (i = 0; i < table_entries; i++) {
    2369                 /* why plus 0x04 ??, That makes the correct value for hash table. */
    2370     outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
    2371     outl(mc_filter[i], ioaddr + rfdr);
    2372   }
    2373 
    2374   outl(RFEN | rx_mode, ioaddr + rfcr);
    2375 
    2376   /* sis900 is capable of looping back packets at MAC level for
    2377    * debugging purpose */
    2378   if (net_dev->flags & IFF_LOOPBACK) {
    2379     u32 cr_saved;
    2380     /* We must disable Tx/Rx before setting loopback mode */
    2381     cr_saved = inl(ioaddr + cr);
    2382     outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);
    2383     /* enable loopback */
    2384     outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);
    2385     outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);
    2386     /* restore cr */
    2387     outl(cr_saved, ioaddr + cr);
    2388   }
    2389 
    2390   return;
    2391 }
    2392 
    23932393
    23942394/**
Note: See TracChangeset for help on using the changeset viewer.